Próbuję przełączyć algorytm, który napisałem z procesora Tesla T10 (możliwość obliczeniowa 1.3) na Tesla M2075 (zdolność obliczeniowa 2.0). Podczas przełączania byłem zaskoczony, że mój algorytm zwolnił. Przeanalizowałem go i odkryłem, że wydaje się, że na nowej maszynie strumienie Cudy są blokowane. Mój algorytm ma 3 główne zadania, które można podzielić i uruchomić równolegle: reorganizację pamięci (która może być wykonana na procesorze), kopiowanie pamięci z hosta na urządzenie i wykonanie jądra na urządzeniu. Na starym rozszczepienia maszynowego strumienie pozwoliło 3 zadania pokrywają się tak (wszystkie zdjęcia z NVidia programu Visual Profiler): Jak określić, dlaczego strumień CUDA blokuje się?
Jednak na nowej maszynie blok strumieni przed rozpoczęciem obliczeń procesora aż do poprzedniego jądra odbywa wykonywania, jak można zobaczyć tutaj:
widać górnym rzędzie, wszystkie bloki pomarańczowe są cudaStreamSynchronize wzywa które blokują aż poprzedni kernel odbywa wykonania, mimo, że jądro jest na zupełnie innym strumieniem. Wydaje się działać po pierwszym przejściu przez strumienie i poprawnie zrównoleglować, ale po tym problem zaczyna się, więc pomyślałem, że być może coś blokowało i próbowałem zwiększyć liczbę strumieni, które dały mi ten wynik:
Tutaj widać, że z jakiegoś powodu blokują się tylko pierwsze 4 strumienie, po czym zaczyna się poprawnie. Jako ostatnia próba próbowałem zhakować dookoła, używając tylko pierwszych 4 strumieni tylko raz, a następnie przełączając się na użycie późniejszych strumieni, ale to wciąż nie działało i nadal blokowało co 4 strumienie, pozwalając jednocześnie na jednoczesne wykonywanie innych strumieni :
Poszukuję więc pomysłów, co może być przyczyną tego problemu i jak go zdiagnozować. Przeczytałem mój kod i nie sądzę, żeby to był błąd, chociaż mógłbym się mylić. Każdy strumień jest hermetyzowany we własnej klasie i ma tylko odniesienie do pojedynczego elementu cudaStream_t, który jest członkiem tej klasy, więc nie widzę, w jaki sposób mógłby odwoływać się do innego strumienia i blokować go.
Czy istnieją pewne zmiany w sposobie pracy strumieni między wersjami 1.3 i 2.0, których nie znam? Czy to może być coś, czemu pamięć współdzielona nie jest wolna i musi na to czekać? Wszelkie pomysły dotyczące diagnozowania tego problemu są mile widziane, dziękuję.
Zastanawiam się, czy Twój problem może być taki sam, jak ostatnio omawiano w następującym wątku na forach NVIDIA: https: //devtalk.nvidia.com/default/topic/545476/cuda-programming-and-performance/cuda-stream-performance/Rozwiązaniem było dodanie opcji 'conckerneltrace' do konfiguracji profilera. – njuffa
Windows lub Linux? której wersji sterownika używasz w każdym przypadku? jakie są parametry uruchamiania dla twoich jąder? czy możesz wysłać jakiś reproduktor? –
W NVIDIA Visual Profiler (CUDA 5.0 i 5.5) dostępna jest również opcja "Włącz współbieżne profilowanie jądra". Przypuszczam, że osiąga to takie same wyniki, jak opcja CLI "conckerneltrace". Zauważ, że potrzebujesz do tego urządzenia CC> = 2.0. – BenC