2011-07-03 4 views
2

Je viens de recevoir ma carte vidéo compatible GPU et j'ai commencé à jouer avec CUDA. Juste pour obtenir la tête droite avec des blocs et des fils, j'ai écrit un noyau simple qui stocke simplement ses identifiants dans la mémoire partagée que je copie plus tard pour héberger et imprimer. Mais alors je pense, pourquoi ne pas simplement utiliser printf à l'intérieur de la fonction du noyau? J'ai essayé cela même si je croyais que c'était impossible. Voici ce que ma tentative ressemblait à:Mon noyau CUDA fonctionne-t-il réellement sur le périphérique ou est-il exécuté par matekenly par l'hôte en émulation?

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

.. mais tout à coup, j'ai vu la sortie dans la console. Ensuite, j'ai recherché le manuel du développeur et trouvé printf mentionné dans la section sur l'émulation de l'appareil. Il a été dit que l'émulation de périphérique offre l'avantage d'exécuter un code spécifique à l'hôte dans le noyau, comme l'appel printf.

Je n'ai pas vraiment besoin d'appeler printf. Mais maintenant je suis un peu confus. J'ai deux hypothèses. Tout d'abord, les développeurs de NVidia ont implémenté un printf spécifique sur un périphérique qui, d'une façon ou d'une autre, permet au développeur d'accéder au processus d'appel et d'exécuter la fonction standard printf. Une autre hypothèse est que le code que j'ai compilé fonctionne d'une manière ou d'une autre en émulation plutôt que sur un périphérique réel. Mais cela ne semble pas correct non plus parce que j'ai simplement mesuré une performance d'ajouter deux nombres sur un tableau de 1 million d'éléments et le noyau CUDA parvient à le faire comme 200 plus vite que je peux faire sur un CPU. Ou peut-être fonctionne-t-il en émulation lorsqu'il détecte un code spécifique à l'hôte? Si c'est vrai, pourquoi ne suis-je pas averti alors?

Aidez-moi s'il vous plaît à trier. J'utilise NVidia GeForce GTX 560 Ti sous Linux (Intel Xeon, 1 CPU avec 4 cœurs physiques, 8 Go de RAM, si ça compte). Voici ma nvcc version:

$ /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 

Et voici comment je compile mon code:

/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 

... et par la manière, à la fois le code hôte et le code noyau est mélangé un fichier source avec l'extension .cu (peut-être que je ne suis pas censé faire cela, mais j'ai vu ce style dans les exemples de SDK).

Votre aide est grandement appréciée. Je vous remercie!

Répondre

4

À partir de CUDA? 3.1?, Ils ne font plus aucune émulation de périphérique. Printf sont maintenant supportés dans le noyau.

+0

de temps en temps, ma mémoire fonctionne .. [Ici] (http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/cudatoolkit_release_notes_linux.txt) la note originale en 3.1 qu'ils facilitent printf() directement depuis le noyau * tant que vous utilisez une carte d'architecture Fermi *. (Lequel est le 560!) –

+0

Il explique tout, parfait. Merci beaucoup! –

Questions connexes