Mein Code ist eine Parallelimplementation, die die n-te Ziffer von pi berechnet. Wenn ich den Kernel fertig mache und versuche, den Speicher zurück auf den Host zu kopieren, bekomme ich einen Fehler "der Start ist abgelaufen und wurde beendet". Ich habe diesen Code zur Fehlerüberprüfung für jeden Start von cudamalloc, cudamemcpy und kernal verwendet.
%Vor%Diese Anrufe sagten, dass alles in Ordnung war, bis zum ersten cudememcpy-Aufruf nach der Rückkehr vom Kernel. Der Fehler tritt in der Zeile "cudaMemcpy (avhost, avdev, size, cudaMemcpyDeviceToHost) auf;" in Haupt. Jede Hilfe wird geschätzt.
%Vor%Dies ist genau das gleiche Problem, zu dem Sie in diese Frage gestellt haben . Der Kernel wird vom Treiber vorzeitig beendet, weil es zu lange dauert, bis er beendet ist. Wenn Sie die Dokumentation für diese Laufzeit-API-Funktionen lesen, sehen Sie folgenden Hinweis:
Hinweis: Beachten Sie, dass diese Funktion auch Fehlercodes von früheren, asynchrone Starts.
Alles was passiert, ist, dass der erste API-Aufruf nach dem Kernel-Start den Fehler zurückgibt, der während der Ausführung des Kernels aufgetreten ist - in diesem Fall der cudaMemcpy-Aufruf. Die Art und Weise, wie Sie dies selbst bestätigen können, besteht darin, direkt nach dem Start des Kernels so etwas zu tun:
%Vor% Der Aufruf cudaPeekAtLastError()
zeigt Ihnen, ob beim Start des Kernels Fehler aufgetreten sind, und der vom Aufruf cudaThreadSynchronize()
zurückgegebene Fehlercode zeigt an, ob während der Ausführung des Kernels Fehler aufgetreten sind.
Die Lösung ist genau wie in der vorherigen Frage beschrieben: wahrscheinlich ist der einfachste Weg, den Code so zu gestalten, dass er wieder "einspringt", sodass Sie die Arbeit über mehrere Kernel-Starts verteilen können, wobei jeder Kernel sicher unter dem Display-Treiber startet Watchdog-Zeitlimit.
Cuda puffert irgendwie alle Lese- / Schreiboperationen auf dem globalen Speicher. So können Sie die Operationen in einer Schleife mit einem Kernel ablaufen lassen, und es wird tatsächlich KEINE ZEIT benötigt. Wenn Sie dann memcpy
aufrufen, sind alle gepufferten Operationen abgeschlossen, und es kann zu einem Timeout kommen. Methode, mit zu gehen, ist cudaThreadSynchronize
Prozedur zwischen Iterationen aufrufen.
Denken Sie also daran: Wenn ein Kernel-Lauf nur wenige Nanosekunden benötigt, bedeutet das nicht, dass er so schnell ist - einige der Schreibvorgänge in den globalen Speicher werden ausgeführt, wenn memcpy
oder threadsynchronize
aufgerufen wird / p>