Ograniczenia rozmiaru siatki w Nvidii CUDA z dwuwymiarową siatką?

Autor:trubshaw

Witam wszystkich. Być może moje pytanie na pierwszy rzut oka okaże się oczywiste, ale mimo to nadal nalegam, żebyś nie uważał tego za głupię, dopóki nie przeczytasz go do końca.

A więc, co jest istotą tego pytania. Jak wiadomo z dokumentacji CUDA, rozmiar siatki uruchamianego jądra ma ograniczenia, które zależą od konkretnego urządzenia. W większości nowoczesnych kart wideo limit wynosi 65535 x 65535 x 1. Na kartach graficznych g210m i 8800gt dokładnie tak sprawdzałem. Ale w tym miejscu spotkałem się z dość dziwną rzeczą - w moim programie, z jakiegoś nieznanego powodu, niemożliwe jest uruchomienie jądra, które miałoby wymiar (wzdłuż wątków) więcej niż 5808x5808 (ta liczba może być mniejsza w zależności od rozmiaru bloku, napisałem ścisłe maksimum ) lub więcej niż 264x264 (jeśli mierzone w blokach) - a ostatnia liczba jest taka sama. Jak tylko liczba uruchomionych bloków przejdzie przez 265x265, jądro się uruchamia, działa, ale w rezultacie zawsze zwraca zero.

Debugger z Nvidia Nsight jest cichy, nie są zgłaszane żadne błędy, profiler pokazuje wyniki pracy, w której uruchamiane jest jądro. Ograniczenie pojawia się na wszystkich kartach graficznych, na których uruchomiłem program - łącznie 8 różnych modeli (8400m g, 8800gt, 9600gso, 8500gt, 9600gt, ION, g210m, gf9300)

Wszystko to sprawia, że ​​myślę, że istnieją ograniczenia nie tylko dotyczące wymiaru siatki, ale także całkowitej liczby wątków w siatce (w końcu istnieje ograniczenie liczby wątków w bloku - czemu by nie było). Tylko tutaj oficjalna dokumentacja, podręcznik Boreskova / Kharlmova, ani przewodnik najlepszych praktyk nie mówią nic o tej ustawie - po prostu mówią, że już na samym początku pytania są wyrażone ograniczenia.

Odkąd to robię od dwóch godzin dziennie przez ostatni tydzień i nie ma postępu, proszę o pomoc - gdzie kopać? Wszelkie komentarze są mile widziane, jeśli potrzebujesz wyjaśnienia - powiedzmy

Komentarze:
Co to znaczy "w rezultacie, zawsze daje zero"? - joanne parkington
Mam na myśli następujące rzeczy:
Logika jest prosta, matryca jest wzięta, wypełniona dwuwymiarowym szeregiem wątków. Tak więc ta macierz nigdy nie może być zerowa, w pierwszym kroku utożsamię ukośne wszystkie przekątne. Niemniej jednak, zarówno podczas debugowania, jak i ostatecznie okazuje się, że macierz składa się tylko i wyłącznie z zer i nie są wydawane żadne błędy. - bhaskar

Odpowiedzi

miguel corte real
Właśnie sprawdzono. Nie udało się powtórzyć problemu.
Mam GTX470.
Tak więc Opublikowano jądro:
 
__global__ void testKernel( int* g_odata) 
{
  if(threadIdx.x==0)
  {
    g_odata[2*(blockIdx.y*gridDim.x+blockIdx.x)] = blockIdx.y;
    g_odata[2*(blockIdx.y*gridDim.x+blockIdx.x)+1] = blockIdx.x;
  }
}

Uruchomiłem go na blokach 8192х8192 i 1024 wątkach (w twoich vidyahach jest maksymalnie 512 wątków w bloku, na Fermi 1024):
 
    dim3  grid( 8192, 8192, 1);
    dim3  threads( 1024, 1, 1);
    testKernel<<< grid, threads, 0 >>>(  d_odata);

Naturalnie przydzielona pamięć itp.
I dostałem ostatni element tablicy: 8191x8191.
Nie testowałem go na dużych liczbach, ponieważ pamięć się kończy :( Musi zostać wdrożona jakaś logika.

Ogólnie nie jest jasne, gdzie masz te nie okrągłe wartości 265, 264?
Odpowiedzi:
Jestem w tym osłupieniu. Wygląda na to, że jakoś popełniłem błąd, ale jakoś to jest zbyt dziwne, że po prostu nie mogę go złapać i program działa prawie wszędzie poprawnie
Dzięki za sprawdzenie! - marysol bishara
I nie można spróbować uruchomić coś takiego:

__global__ void testKernel (int * g_odata)
{
 int indexX = blockIdx.x * blockDim.x + threadIdx.x;
 int indexY = blockIdx.y * blockDim.y + threadIdx.y;
 if (indexX == 2097088 && indexY == 2097088)
 {
 g_odata [0] = indexX;
 g_odata [1] = indexY;
 }
 __suncthreads ();
}

dim3 grid (65534, 65534, 1);
dim3 thread (32, 32, 1);
testKernel & lt; & lt; & lt; wątki siatki, 0> (d_odata); - carolyn kriete
Próbowałem. W szczególności twój kod ulega awarii po przekroczeniu limitu czasu. Przeczytaj więcej na temat limitów czasu tutaj: forums.nvidia.com/lofiversion/index.php?t106635.html.

Nieco modyfikacja kodu przyniosła taki wynik:
Sprawdzanie 1x1
Czas przetwarzania: 55,926998 (ms)
Ostatnie 31x31
 -
Sprawdzanie 2x2
Czas przetwarzania: 0,098000 (ms)
Ostatnie 63x63
 -
...
 - Sprawdzanie 256x256
Czas przetwarzania: 3.470000 (ms)
Ostatnie 8191 x 8191
 - ...
 - Sprawdzanie 8192x8192
Czas przetwarzania: 3465.157959 (ms)
Ostatnie 262143 x 262143
 - Sprawdzanie 16384x16384
Czas przetwarzania: 13827.656250 (ms)
Ostatnie 524287x524287
 - Sprawdzanie 32768x32768
template.cu (98): cudaSafeCall () Runtime API error: limit czasu uruchomienia został zakończony.
- merrily
Dziękujemy za to, czego potrzebujesz.
Więc mam gdzieś błąd, z żalem - tosit agarwal
Wyświetlanie oceny odpowiedzi w q & amp; amp; podczas oglądania wszystkich moich odpowiedzi? :: Pytanie o archiwizację kopii zapasowej :: Shift + Delete w systemie Mac OS X :: Amazon EC2 :: Jakie jest znaczenie zamkniętych blogów na temat Habré?
Zostaw odpowiedź
Linki