Мое ядро ​​CUDA действительно работает на устройстве или по ошибке выполняется хостом в эмуляции? - PullRequest
2 голосов
/ 03 июля 2011

Я только что получил мою видеокарту с поддержкой графического процессора и начал играть с CUDA. Просто, чтобы разобраться с блоками и потоками, я написал простое ядро, которое просто сохраняет свои идентификаторы в общей памяти, которые позже я копирую обратно на хост и печатаю. Но тогда я думаю, почему бы просто не использовать printf внутри функции ядра? Я попробовал это, хотя я полагал, что это было невозможно. Вот как выглядела моя попытка:

__global__ void
printThreadXInfo (int *data)
{
    int i = threadIdx.x;
    data[i] = i;
    printf ("%d\n", i);
}

.. но внезапно я увидел вывод в консоли. Затем я искал руководство разработчика и обнаружил printf, упомянутый в разделе об эмуляции устройства. Было сказано, что эмуляция устройства дает преимущество запуска кода ядра в ядре, например, вызова printf.

Мне действительно не нужно звонить printf. Но сейчас я немного растерялся. У меня есть два предположения. Во-первых, разработчики NVidia реализовали специальное printf на устройстве, которое каким-то образом прозрачно для разработчика обращается к вызывающему процессу и выполняет стандартную функцию printf, а также заботится о копировании памяти и т. Д. Это звучит немного безумно. Другое предположение состоит в том, что скомпилированный код каким-то образом работает в режиме эмуляции, а не на реальном устройстве. Но это тоже звучит неправильно, потому что я просто измерил производительность сложения двух чисел в массиве из 1 миллиона элементов, и ядру CUDA удалось сделать это примерно на 200 быстрее, чем я могу сделать на процессоре. Или, может быть, он работает в режиме эмуляции, когда обнаруживает некоторый специфичный для хоста код? Если это правда, то почему я не выпустил предупреждение?

Пожалуйста, помогите мне разобраться. Я использую NVidia GeForce GTX 560 Ti в Linux (Intel Xeon, 1 процессор с 4 физическими ядрами, 8 ГБ оперативной памяти, если это имеет значение). Вот моя nvcc версия:

$ /usr/local/cuda/bin/nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2011 NVIDIA Corporation
Built on Thu_May_12_11:09:45_PDT_2011
Cuda compilation tools, release 4.0, V0.2.1221

А вот как я компилирую свой код:

/usr/local/cuda/bin/nvcc -gencode=arch=compute_20,code=\"sm_21,compute_20\" -m64 --compiler-options -fno-strict-aliasing -isystem /opt/boost_1_46_1/include -isystem /usr/local/cuda/include -I../include --compiler-bindir "/usr/local/cuda/bin" -O3 -DNDEBUG -o build_linux_release/ThreadIdxTest.cu.o -c ThreadIdxTest.cu

/usr/local/cuda/bin/nvcc -gencode=arch=compute_20,code=\"sm_21,compute_20\" -m64 --compiler-options -fno-strict-aliasing -isystem /opt/boost_1_46_1/include -isystem /usr/local/cuda/include -I../include --compiler-bindir "/usr/local/cuda/bin" -O3 -DNDEBUG --generate-dependencies ThreadIdxTest.cu | sed -e "s;ThreadIdxTest.o;build_linux_release/ThreadIdxTest.cu.o;g" > build_linux_release/ThreadIdxTest.d

g++ -pipe -m64 -ftemplate-depth-1024 -fno-strict-aliasing -fPIC -pthread -DNDEBUG -fomit-frame-pointer -momit-leaf-frame-pointer -fno-tree-pre -falign-loops -Wuninitialized -Wstrict-aliasing -ftree-vectorize -ftree-loop-linear -funroll-loops -fsched-interblock -march=native -mtune=native -g0 -O3 -ffor-scope -fuse-cxa-atexit -fvisibility-inlines-hidden -Wall -Wextra -Wreorder -Wcast-align -Winit-self -Wmissing-braces -Wmissing-include-dirs -Wswitch-enum -Wunused-parameter -Wredundant-decls -Wreturn-type -isystem /opt/boost_1_46_1/include -isystem /usr/local/cuda/include -I../include -L/opt/boost_1_46_1/lib -L/usr/local/cuda/lib64 -lcudart -lgtest -lgtest_main build_linux_release/ThreadIdxTest.cu.o ../src/build_linux_release/libspartan.a -o build_linux_release/ThreadIdxTest

... и, кстати, и код хоста, и код ядра смешаны в одном исходном файле с расширением .cu (возможно, я не должен этого делать, но я видел этот стиль в примерах SDK).

Ваша помощь высоко ценится. Спасибо!

1 Ответ

4 голосов
/ 03 июля 2011

Начиная с CUDA? 3.1? Они больше не делают эмуляцию устройства . Printf теперь поддерживаются в ядре.

...