Sto provando a cambiare un algoritmo che avevo scritto da un processore Tesla T10 (capacità di calcolo 1.3) a un Tesla M2075 (capacità di calcolo 2.0). Durante il passaggio sono rimasto sorpreso nel constatare che il mio algoritmo ha rallentato. L'ho analizzato e ho scoperto che sembra essere perché sulla nuova macchina i flussi di cuda stanno bloccando. Il mio algoritmo ha 3 attività principali che possono essere suddivise ed eseguite in parallelo: riorganizzazione della memoria (che può essere eseguita sulla CPU), copia della memoria dall'host al dispositivo e esecuzione del kernel sul dispositivo. Sul vecchio splitting macchina i flussi consentiti i 3 compiti si sovrappongono come questo (tutte le immagini dalla NVidia visiva Profiler): Come determinare il motivo per cui uno stream CUDA sta bloccando
Tuttavia sulla nuova macchina il blocco corsi d'acqua prima di iniziare il calcolo della CPU fino a quando il kernel precedente è fatto l'esecuzione, come si può vedere qui:
potete vedere la riga superiore, tutti i blocchi arancioni sono il cudaStreamSynchronize chiama quale blocco fino a quando il kernel precedente è fatto l'esecuzione, anche se questo kernel è su un flusso completamente diverso. Sembra funzionare per la prima volta attraverso i flussi e parallelizza correttamente, ma dopo inizia il problema, quindi ho pensato che forse stava bloccando qualcosa e ho cercato di aumentare il numero di flussi che mi hanno dato questo risultato:
Qui si può vedere che per qualche motivo solo i primi 4 flussi stanno bloccando, dopodiché inizia a parallelizzare correttamente. Come ultimo tentativo ho cercato di aggirarlo usando solo i primi 4 stream per una sola volta e poi passando a utilizzare i flussi successivi ma non funzionava ancora e si bloccava ancora ogni 4 flussi lasciando che gli altri stream venissero eseguiti simultaneamente :
Quindi sto cercando idee su cosa potrebbe causare questo problema e su come diagnosticarlo. Ho studiato il mio codice e non penso che sia un bug lì, anche se potrei sbagliarmi. Ogni stream è incapsulato nella propria classe e ha solo un riferimento a un singolo cudaStream_t che è un membro di quella classe, quindi non vedo come potrebbe fare riferimento a un altro stream e a bloccarlo.
Ci sono dei cambiamenti nel modo in cui gli stream funzionano tra la versione 1.3 e 2.0 di cui non sono a conoscenza? Potrebbe essere qualcosa con la memoria condivisa non essere liberata e dover aspettare su quello? Qualsiasi idea su come diagnosticare questo problema è gradita, grazie.
Mi chiedo se il problema potrebbe essere lo stesso di quello recentemente discusso nella discussione seguente nei forum NVIDIA: https: //devtalk.nvidia.com/default/topic/545476/cuda-programming-and-performance/cuda-stream-performance/La soluzione è stata aggiungere l'opzione 'conckerneltrace' all'impostazione del profiler. – njuffa
windows o linux? quale versione di driver stai usando in ogni caso? quali sono i parametri di lancio per i tuoi kernel? puoi pubblicare un riproduttore di qualche tipo? –
In NVIDIA Visual Profiler (CUDA 5.0 e 5.5), esiste anche un'opzione 'Abilita profilo di kernel simultaneo'. Suppongo che questo ottenga gli stessi risultati dell'opzione CLI 'conckerneltrace'. Nota che hai bisogno di un dispositivo CC> = 2.0 per quello. – BenC