私はGPU対応のビデオカードを手に入れて、CUDAで遊ぶことができました。ブロックとスレッドを使って私の頭をまっすぐにするために、シンプルなカーネルを作成しました。そのカーネルは共有メモリに識別子を格納するだけで、あとでホストして印刷することができます。しかし、私は、カーネルの機能の中で単にprintf
を使用してみませんか?私はそれが不可能だと信じていましたが、私はそれを試みました。私の試みは次のようになりました。私のCUDAカーネルは実際にデバイス上で動作していますか、エミュレーションでホストによって間違って実行されていますか?
__global__ void
printThreadXInfo (int *data)
{
int i = threadIdx.x;
data[i] = i;
printf ("%d\n", i);
}
..突然私はコンソールで出力を見ました。次に、開発者マニュアルを検索し、デバイスエミュレーションに関するセクションで説明したprintf
が見つかりました。デバイスのエミュレーションは、printf
のように、ホスト固有のコードをカーネル内で実行する利点があります。
printf
に電話する必要はありません。しかし、今私はちょっと混乱しています。私は2つの仮定があります。まず、NVidiaの開発者がデバイス上に具体的にprintf
を実装しました。開発者が何らかの方法で透過的にプロセスを呼び出し、標準printf
という標準機能を実行してアクセスし、メモリのコピーなどを行いました。別の前提として、私がコンパイルしたコードは、実際のデバイスではなく、エミュレーションで動作するということです。しかし、CUDAカーネルは100万要素の配列に2つの数値を追加するだけの性能を測定しただけで、CPUでできるよりも200倍高速に処理することができます。それとも、ホスト固有のコードが検出されたときにエミュレーションで実行されるのでしょうか?それが真実なら、なぜ私は警告を発しませんでしたか?
私はそれを整理するのを手伝ってください。私はLinux上でNVidia GeForce GTX 560 Tiを使用しています(Intel Xeon、4個の物理コアを持つ1個のCPU、8 GBのRAM、重要な場合)。
$ /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
そして、ここでは、私は私のコードをコンパイルする方法である:ここに私のnvcc
バージョンである
/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
は...と方法によって、ホスト・コードとカーネルコードの両方が中に混合されます1つのソースファイル.cu
(おそらく私はそれを行うはずはありませんが、私はSDKの例でこのスタイルを見た)。
お手数をおかけしますようお願い申し上げます。ありがとうございました!
長い間、私の記憶が働いています.. [ここ](http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/cudatoolkit_release_notes_linux.txt)3.1のオリジナルノートフェルミアーキテクチャーカード*を使用している限り、カーネル*から直接printf()を容易にすることができます。 (どれが560です!) –
それはすべて、それを完璧に説明します。どうもありがとうございました! –