我的问题非常像这个one。我运行最简单的CUDA程序,但内核没有启动。但是,我确信我的CUDA安装没问题,因为我可以运行复杂的CUDA项目,包括几个文件(我从其他人那里拿走),没有任何问题。在这些项目中,编译和链接是通过带有大量标志的makefile完成的。我认为问题在于编译时使用的正确标志。我只是使用这样的命令:nvcc -arch=sm_20 -lcudart test.cu
与这样的程序(在Linux机器上运行):
__global__ void myKernel()
{
cuPrintf("Hello, world from the device!\n");
}
int main()
{
cudaPrintfInit();
myKernel<<<1,10>>>();
cudaPrintfDisplay(stdout, true);
cudaPrintfEnd();
}
该程序正确编译。当我添加cudaMemcpy()操作时,它不会返回任何错误。关于为什么内核不启动的任何建议?
您确定您的CUDA设备支持SM_20架构吗?
从nvcc命令行中删除arch =选项并重建所有内容。这将编译1.0 CUDA架构,这将在所有CUDA设备上得到支持。如果它仍然没有运行,请执行构建清理并确保没有任何目标文件留在任何位置。然后重建并运行。
此外,arch =指的是虚拟架构,它应该类似于compute_10。 sm_20是真正的架构,我相信应该与code = switch一起使用,而不是arch =。
使用printf
时不打印的原因是内核启动是异步的,并且在刷新printf缓冲区之前程序正在退出。 CUDA(5.0)C编程指南的B.16节解释了这一点。
在内核启动之前,printf()的输出缓冲区设置为固定大小(请参阅关联的主机端API)。它是循环的,如果在内核执行期间产生的输出多于缓冲区中的输出,则会覆盖旧的输出。仅在执行以下操作之一时才刷新:
- 通过<<< >>>或cuLaunchKernel()启动内核(在启动开始时,如果CUDA_LAUNCH_BLOCKING环境变量设置为1,则在启动结束时),
- 通过cudaDeviceSynchronize(),cuCtxSynchronize(),cudaStreamSynchronize(),cuStreamSynchronize(),cudaEventSynchronize()或cuEventSynchronize()进行同步,
- 内存副本通过任何阻止版本的cudaMemcpy *()或cuMemcpy *(),
- 通过cuModuleLoad()或cuModuleUnload()加载/卸载模块,
- 通过cudaDeviceReset()或cuCtxDestroy()进行上下文破坏。
因此,此程序不打印任何内容:
#include <stdio.h>
__global__ void myKernel()
{
printf("Hello, world from the device!\n");
}
int main()
{
myKernel<<<1,10>>>();
}
但是这个程序打印了“Hello,world from the device!\ n”十次。
#include <stdio.h>
__global__ void myKernel()
{
printf("Hello, world from the device!\n");
}
int main()
{
myKernel<<<1,10>>>();
cudaDeviceSynchronize();
}
在Visual Studio中:
右键单击项目> Properties> Cuda C / C ++> Device
然后在代码生成字段中添加
compute_30,sm_30;compute_35,sm_35;compute_37,sm_37;compute_50,sm_50;compute_52,sm_52;compute_60,sm_60;compute_61,sm_61;compute_70,sm_70;compute_75,sm_75;
为所有这些架构生成代码会使代码变慢。因此,逐一消除,找出GPU所需的compute
和sm
代码。但是如果你把它发送给其他人更好地包括所有这些。