注意随着 CUDA Toolkit 3.2 版的发布,NVIDIA 现在将规则文件包含在 Toolkit 中,而不是 SDK。因此,我将这个答案分成两半,对您的工具包版本使用正确的说明。
注意这些说明适用于 Visual Studio 2005 和 2008。对于 Visual Studio 2010,请参阅此答案。
CUDA 工具包 3.2 及更高版本
我建议使用 NVIDIA 提供的NvCudaRuntimeApi.rules
文件(或者NvCudaDriverApi.rules
如果使用驱动程序 API),它随工具包一起发布,并以友好的方式支持最新的编译器标志。我个人建议不要使用 VS 向导,但这只是因为我真的认为你不需要它。
规则文件(安装到Program Files\Microsoft Visual Studio 9.0\VC\VCProjectDefaults
目录中)“教”Visual Studio 如何编译项目中的任何 .cu 文件并将其链接到应用程序中。
- 使用标准 MS 向导创建一个新项目(例如一个空的控制台项目)
- 在 .c 或 .cpp 文件中实现您的主机(串行)代码
- 在 .cu 文件中实现包装器和内核
- 添加
NvCudaRuntimeApi.rules
(右键单击项目,自定义构建规则,勾选相关框),见注1
- 添加 CUDA 运行时库(右键单击项目并选择Properties,然后在Linker -> General添加
$(CUDA_PATH)\lib\$(PlatformName)
到Additional Library Directories并在Linker -> Input添加cudart.lib
到Additional Dependencies),参见注释 [2] 和 [3]
- 可选择将 CUDA 包含文件添加到搜索路径,如果您在 .cpp 文件(而不是 .cu 文件)中包含任何 CUDA 文件,则需要(右键单击项目并选择Properties,然后在C/C++ -> General添加附加包含目录
$(CUDA_PATH)\include
),请参阅注释 [3]
- 然后只需构建您的项目,.cu 文件将被编译为 .obj 并自动添加到链接中
其他一些提示:
- 更改代码生成以使用静态加载的 C 运行时以匹配 CUDA 运行时;右键单击项目并选择Properties,然后在C/C++ -> Code Generation中将Runtime Library更改为 /MT (或 /MTd 进行调试,在这种情况下,您需要在Runtime API -> Host -> Runtime中进行镜像库),见注[4]
- 使用 SDK 中包含的 usertype.dat 文件启用语法高亮,请参阅 readme.txt
<sdk_install_dir>\C\doc\syntax_highlighting\visual_studio_8
我还建议使用以下注册表项启用 Intellisense 支持(将 9.0 替换为 8.0 用于 VS2005 而不是 VS2008):
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Languages\Language Services\C/C++]
"NCB Default C/C++ Extensions"=".cpp;.cxx;.c;.cc;.h;.hh;.hxx;.hpp;.inl;.tlh;.tli;.cu;.cuh;.cl"
顺便说一句,如果可能的话,我会提倡避免使用 cutil,而是自己进行检查。Cutil 不受 NVIDIA 支持,它只是用来尝试使 SDK 中的示例专注于实际的程序和算法设计,并避免在每个示例中重复相同的内容(例如命令行解析)。如果您自己编写,那么您将有更好的控制,并且会知道发生了什么。例如,如果函数失败,cutilSafeCall
包装器会调用exit()
——一个真实的应用程序(而不是一个示例)可能应该更优雅地处理失败!
CUDA 工具包 3.1 及更早版本
我会将Cuda.rules
NVIDIA 提供的文件与 SDK 一起使用,它与工具包一起发布,并以友好的方式支持最新的编译器标志。我个人建议不要使用 VS 向导,但这只是因为我真的认为你不需要它。
规则文件(位于 SDK 的C\common目录中)“教”Visual Studio 如何编译项目中的任何 .cu 文件并将其链接到应用程序中。
- 使用标准 MS 向导创建一个新项目(例如一个空的控制台项目)
- 在 .c 或 .cpp 文件中实现您的主机(串行)代码
- 在 .cu 文件中实现包装器和内核
- 添加
Cuda.rules
(右键单击项目,自定义构建规则,浏览规则文件并确保它被勾选)
- 添加 CUDA 运行时库(右键单击项目并选择Properties,然后在Linker -> General添加
$(CUDA_LIB_PATH)
到Additional Library Directories并在Linker -> Input添加cudart.lib
到Additional Dependencies),请参见下面的注释 [2]
- 可选择将 CUDA 包含文件添加到搜索路径,如果您在 .cpp 文件(而不是 .cu 文件)中包含任何 CUDA 文件,则需要(右键单击项目并选择Properties,然后在C/C++ -> General添加
$(CUDA_INC_PATH)
到附加包含目录)
- 然后只需构建您的项目,.cu 文件将被编译为 .obj 并自动添加到链接中
其他一些提示:
- 将代码生成更改为使用静态加载的 C 运行时以匹配 CUDA 运行时,右键单击项目并选择Properties,然后在C/C++ -> Code Generation中将Runtime Library更改为 /MT(或 /MTd 进行调试,其中如果您需要在CUDA Build Rule -> Hybrid CUDA/C++ Options中镜像此内容),请参阅注释 [4]
- 使用 SDK 中包含的 usertype.dat 文件启用语法高亮,请参阅 readme.txt
<sdk_install_dir>\C\doc\syntax_highlighting\visual_studio_8
我还建议使用以下注册表项启用 Intellisense 支持(将 9.0 替换为 8.0 用于 VS2005 而不是 VS2008):
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Languages\Language Services\C/C++]
"NCB Default C/C++ Extensions"=".cpp;.cxx;.c;.cc;.h;.hh;.hxx;.hpp;.inl;.tlh;.tli;.cu;.cuh;.cl"
顺便说一句,如果可能的话,我会提倡避免使用 cutil,而是自己进行检查。Cutil 不受 NVIDIA 支持,它只是用来尝试使 SDK 中的示例专注于实际的程序和算法设计,并避免在每个示例中重复相同的内容(例如命令行解析)。如果您自己编写,那么您将有更好的控制,并且会知道发生了什么。例如,如果函数失败,cutilSafeCall
包装器会调用exit()
——一个真实的应用程序(而不是一个示例)可能应该更优雅地处理失败!
笔记
- 您还可以使用特定于 Toolkit 版本的规则,例如
NvCudaRuntimeApi.v3.2.rules
. 这意味着不是在 %CUDA_PATH% 中查找 CUDA Toolkit,而是在 %CUDA_PATH_V3_2% 中查找,这反过来意味着您可以在系统上安装多个版本的 CUDA Toolkit,并且不同的项目可以针对不同的版本。另见注释 [3]。
- 规则文件不能修改 C/C++ 编译和链接器设置,因为它只是为 CUDA 代码添加编译设置。因此,您需要手动执行此步骤。记住对所有配置都这样做!
- 如果您想稳定在特定的 CUDA Toolkit 版本上,则应将 CUDA_PATH 替换为 CUDA_PATH_V3_2。另见注1。
- C 运行时版本不匹配会导致各种问题;特别是如果您对 LIBCMT(例如
LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
)或标准库函数的多重定义符号有任何错误,那么这应该是您的第一个嫌疑人。