我刚拿到支持GPU的视频卡并开始玩CUDA。为了直接了解块和线程,我编写了一个简单的内核,它只将其标识符存储到共享内存中,然后我将其复制回主机并进行打印。但是,那么我为什么不在内核函数中简单地使用printf
呢?尽管我相信这是不可能的,但我已经尝试过了。这是我的尝试:
__global__ void
printThreadXInfo (int *data)
{
int i = threadIdx.x;
data[i] = i;
printf ("%d\n", i);
}
..但突然之间我在控制台看到了输出。然后我搜索了开发人员的手册,发现了有关设备模拟的部分中提到的printf
。据说,设备仿真提供了在内核中运行特定于主机的代码的好处,比如调用printf
。
我真的不需要致电printf
。但现在我有点困惑。我有两个假设。首先,NVidia开发人员在设备上实现了一些特定的printf
,以某种方式透明地让开发人员访问调用进程并执行标准printf
函数,并负责内存复制等。这听起来有点疯狂。另一个假设是我编译的代码以某种方式运行在仿真而不是真实设备上。但这听起来不对,因为我只是测量了在100万个元素阵列上添加两个数字的性能,而CUDA内核设法比在CPU上做得快200个。或者它可能在检测到某些特定于主机的代码时运行仿真?如果这是真的,为什么我没有发出警告呢?
请帮我解决一下。我在Linux上使用NVidia GeForce GTX 560 Ti(Intel Xeon,1个CPU,4个物理内核,8 GB RAM,如果这很重要)。这是我的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示例中看到了这种风格)。
非常感谢您的帮助。谢谢!
答案 0 :(得分:4)
从CUDA?3.1?开始,他们不再进行任何设备仿真。现在内核支持Printf。