下面是我测试Fermi的一些printf()"新"功能,我发现有两个问题没有想通,代码是看ice版主发给我的Fermi+tips.pdf中的,
问题一:mallocTest() 中的printf()没有执行,因为看不到输出;
问题二:当我把//mallocTest<<<1,5>>>();屏蔽了之后,连helloWorld()中的printf()都失效了,这是为什么?
想不通啊!
__global__ void helloWorld()
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
printf("Thread %d: Hello, World!\n", tid); // GPU calls CPU function
}
__global__ void mallocTest()
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
char* ptr = (char*)malloc(123);
printf("Thread %d got pointer: %p\n", tid, ptr);
free(ptr);
}
int main(void)
{
helloWorld<<<1,3>>>();
mallocTest<<<1,5>>>();
return 0;
}
其实结果已经有了,只是没有等到刷新到屏幕上程序就已经结束了.请在return之前加上cudaDeviceReset()函数,这能够保证printf结果一定会显示到屏幕上.
Right!
[
[attach]2860[/attach]
核函数里可以用printf()函数么?为什么我的gpu里用不了呢?我用的是xp系统。
可以用的,需要fermi或者kepler的核心的GPU,programming guide里面应当有说明。
祝您编码愉快!
原来如此,我的是Gforce。谢了……
不是的,geforce只是产品系列的名称,现在卖的geforce也都是fermi和kepler核心的,以前的telsa也不是fermi和kepler核心。
一般来说,400系列以及以后的都是fermi和kepler,而像更早的geforce GTX 2xx,geforce 9800GT之类是更早的核心,不支持在kerne里面printf。
您可以运行一下device query,看看计算能力是多少的,2.0或者2.0以上的都可以,1.x的不行。
祝您愉快~
您看我这个计算能力,是不是属于3.0的啊?
那是因为你编译的时候compute和sm默认都是10,需要改成30才能使用内核里德printf
您的设备的计算能力是3.0的,是kepler核心的,其他请参考10# tianyuan版主的意见。
请问如何才能将它两改为10啊?谢谢您!
奥……是如何才能改为30才是啊.
如果用的是VS,解决方案名称——右键属性——配置属性——CUDA Runtime API——GPU——GPU Architecture sm_30。或者在命令行里面改也可以。
linux神马的我就不懂了。
但是GPU Architecture有3个啊,后面分别跟了(1)(2)(3),我应该改那个呢?
把原有的sm_10拿掉,换成sm——30应该就OK了。
这里有三项应该是编译的时候生成3种不同架构的二进制码。
为什么会出现这种情况呢?执行了一句话,就会出现相应的结果啊,都还没有打印出来,程序怎么就结束了呢?
具体的原因我不是很清楚,不过可以无责任估计一下,因为据某种来源的分析,kernel里面实现printf实际上是在后台实现了一次和host的交互,然后交由host端实现的,而不是直接由GPU实现(其实GPU想实现也实现不了,它不能直接在host端干事情。)。所以这里面可能有延迟或者某些机制影响,造成邻近结尾的printf没输出。
鉴于上述说法是本人在道听途说的基础上酱油分析的,所以无法保证其正确性,仅供参考(亦或揭批)。
祝您编码愉快。
很愉快能分享您的见解!也祝你愉快,ice版主!
需要补充一下18#的说法。
根据programming guide(CUDA 4.2)的B.15章节的说法,kernel端的打印信息是写入一个缓冲区的,最后是被host端执行。当有主机端和设备端同步的命令时,可以保证将缓冲区内部的内容都输出出来。以及给出了程序末尾如果没有正确打印出来的话,建议添加cudaDeviceReset()等的内容。
详情请查阅CUDA C programming guide.