Mój przykład dodawania macierzy:

 __global__ void matrix_add(float *a, float*b, float *c, int N)
{
    int index;
    int Row = blockIdx.y * blockDim.y + threadIdx.y;
    int Col = blockIdx.x * blockDim.x + threadIdx.x;

    int index = Row * N + Col;      // N is the order of the square matrix

    cd[index]= ad[index] + bd[index];

}

Czy mogę użyć printf lub innej podobnej funkcji w powyższym jądrze? Abym nie musiał przesyłać danych z urządzenia do pamięci hosta (tj. cudaMemcpyDeviceToHost). Jeśli tak, to w jaki sposób? Jeśli nie, to dlaczego nie?

0
sandeep.ganage 19 październik 2012, 14:46

2 odpowiedzi

Najlepsza odpowiedź

Możesz użyć printf(..), ale tylko dla cc2.x lub nowszego.
Możesz przeczytać więcej na ten temat w przewodniku programowania CUDA, Dodatek B.16.

1
brano 19 październik 2012, 14:52

Jedynym sposobem wyświetlenia wyników z jądra bez powodowania kopiowania danych z powrotem do hosta jest użycie jednego z trybów współdziałania grafiki. CUDA obsługuje współdziałanie OpenGL i Direct3D. Przykłady, jak z nich korzystać, znajdują się w Przewodniku programowania CUDA.

__device__ printf() (przy możliwościach obliczeniowych >= 2.0) i __device__ cuPrintf() (przy możliwościach obliczeniowych < 2.0), oba powodują niejawne kopiowanie drukowanych ciągów z powrotem do hosta. Bardzo prawdopodobne, że obie te metody powodują również niejawną serializację wszystkich jąder, które próbują drukować w tym samym czasie, dlatego są zwykle używane tylko do debugowania.

Jeśli uruchomisz aplikację CUDA w debugerze, wartości urządzeń wyświetlane w debugerze również zostały niejawnie skopiowane do hosta.

Z twojego pytania nie jest jasne, czy chcesz uniknąć kopiowania wartości z powrotem do hosta, czy też chcesz tylko uniknąć konieczności jasnego kopiowania wartości. Jeśli jest to drugie, to metody __device__ printf() są odpowiednie do wyświetlania niewielkich ilości wyników na hoście. Innym sposobem uniknięcia konieczności jawnego kopiowania wartości jest użycie thrust::device_vector. Thrust to biblioteka dostarczana z CUDA. Jest inspirowany C++ STL. Możesz czytać i pisać do device_vector po stronie hosta, a niejawne kopie są wykonywane do iz urządzenia w tle.

Możesz również spowodować niejawne kopiowanie, używając tak zwanej pamięci mapowanej. Dzięki pamięci mapowanej sprzęt CUDA może wykonywać niejawne kopiowanie pamięci między hostem a urządzeniem, zgodnie z wymaganiami jądra.

Powodem tego wszystkiego jest to, że kopie między hostem a urządzeniem są bardzo drogie. Zazwyczaj zajmują dużą część całkowitego czasu obliczeniowego. Dlatego należy dokładnie rozważyć, kiedy i jak te kopie mają miejsce. Wszystkie techniki, o których wspomniałem, mają różne konsekwencje dla wydajności, a sposób najlepszego radzenia sobie z kopiowaniem zależy od aplikacji.

1
Roger Dahl 19 październik 2012, 19:17