Warum kann ich Datenübertragungen und Berechnungen mit GTX 480 und CUDA 5 nicht überlappen?
Ich habe versucht, Kernel-Ausführungen mit memcpyasync zu überlappen, aber es funktioniert nicht. Ich befolge alle Empfehlungen im Programmierhandbuch, verwende fixierten Speicher, verschiedene Streams usw. Ich sehe, dass sich die Kernelausführung zwar überlappt, aber nicht mit Mem-Übertragungen. Ich weiß, dass meine Karte nur eine Kopier- und eine Ausführungs-Engine hat, aber Ausführung und Übertragung sollten sich überschneiden, oder?
Es scheint, dass die "Copy Engine" und "Execution Engine" immer die Reihenfolge erzwingen, in der ich die Funktionen aufrufe. Die Arbeit besteht aus 4 Streams, die [HtoD x2, Kernel, DtoH] ausführen. Wenn ich HtoDx2-, Kernel-, DtoH-Serien für jeden Stream stelle, sehe ich im Profiler, dass die erste HtoD-Operation von stream2 erst startet, wenn die erste DtoH-Operation endet. Wenn ich zuerst das HtoD für jeden Stream ausstelle, dann das zweite HtoD, dann den Kernel und dann DtoH (Breite), sehe ich keine Überlappung und die Ausgabereihenfolge wird auch von der GPU erzwungen.
Ich habe es mit dem in CUDA SDK angegebenen simpleStreams-Beispiel versucht und sehe auch dasselbe Verhalten.
Ich füge einige Screenshots bei, die das Problem sowohl in Visual Profiler als auch in Nsight für VS2008 zeigen.
ps. Ich habe die CUDA_LAUNCH_BLOCKING-Umgebung nicht festgelegt
Simple Streams Visual Profiler
Die Breite der MyApp Nsight-Timeline steht an erster Stelle
MyApp Nsight Timeline-Tiefe zuerst
bearbeiten:
Zusätzliche x4-Kernel setzen (insgesamt 2HtoD, 5 Kernel, 1DtoH pro Stream) -> Wenn ich nvprof mit und ohne --concurrent-kernels-off starte, ist die verstrichene Zeit dieselbe. Wenn ich die env CUDA_LAUNCH_BLOCKING = 1 setze, sehe ich eine Leistungsverbesserung (von der Kommandozeile aus) von 7,5%!
System Spezifikation:
Windows 7NVIDIA 6800 VGA im ersten PCI-E-SteckplatzGTX480 im zweiten PCI-E-SteckplatzNVIDIA-Treiber: 306,94Visual Studio 2008CUDA v5.0Visual Profiler 5.0Nsight 3.0