2011-07-03 10 views
2

私は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の例でこのスタイルを見た)。

お手数をおかけしますようお願い申し上げます。ありがとうございました!

答えて

4

CUDA®3.1以降では、デバイスのエミュレーションであるは、もはやになりません。 Printfは現在カーネルでサポートされています。

+0

長い間、私の記憶が働いています.. [ここ](http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/cudatoolkit_release_notes_linux.txt)3.1のオリジナルノートフェルミアーキテクチャーカード*を使用している限り、カーネル*から直接printf()を容易にすることができます。 (どれが560です!) –

+0

それはすべて、それを完璧に説明します。どうもありがとうございました! –

関連する問題