【VS开发】【CUDA开发】如何在MFC中调用CUDA

来源:互联网 发布:avmoo 2016.7最新域名 编辑:程序博客网 时间:2024/05/16 04:45

如何在MFC中调用CUDA

       有时候,我们需要在比较大的项目中调用CUDA,这就涉及到MFC+CUDA的环境配置问题,以矩阵相乘为例,在MFC中调用CUDA程序。我们参考罗振东iylzd@163.com(国防科学技术大学计算机学院)的方法。

 

环境: Windows 7 SP1

              Microsoft Visual Studio 2010

              CUDA 5.0

 

步骤:

 

1.首先建立一个空的名叫Matrix Multiplication_KahanMFC的“FCM应用程序”项目:

 

如何在MFC中调用CUDA

点击“确定”,这时弹出如下窗口

如何在MFC中调用CUDA

       我们需要对默认项目进行一些修改,点击“下一步”,我们设置一个空的MFC项目,选择“单个文档”和“MFC标准”:

如何在MFC中调用CUDA

点击“完成”。

2.创建CUDA的调用接口函数及其头文件

       1)头文件

       “添加”--> “新建项”-->Visual C++-->“头文件(.h)”-->“名称”-->CUDA_Transfer.h -->“添加”,如下图:

 

如何在MFC中调用CUDA

CUDA_Transfer.h中添加如下代码:

//CUDA_Transfer.h

 

#include

#include "math.h"

 

using namespace std;

 

int run_cuda(float* GPU, float* CPU);

如下图所示:

如何在MFC中调用CUDA

       2)函数

       按照和增加头文件相似的方法,添加函数。“添加”--> “新建项”-->Visual C++-->C++文件(.cpp)” -->“名称”-->CUDA_Transfer.cpp -->“添加”,如下图:

如何在MFC中调用CUDA

CUDA_Transfer.cpp中添加如下代码:

//CUDA_Transfer.cpp

#include "CUDA_Transfer.h"

#include "stdafx.h"

 

extern "C" int runtest(float* GPU, float* CPU);

 

int run_cuda(float* GPU, float* CPU)

{

         runtest(GPU,CPU);

         return 0;

}

如下图所示:

如何在MFC中调用CUDA

       需要注意的是在MFC的文件中是不能包含(include.cu文件的,会报错,所以我们使用extern "C"的方式来实现函数的调用。

3. 创建存放cuda 代码的筛选器,名为CUDA

       “添加”--> “新建筛选器”,重命名为CUDA

如何在MFC中调用CUDA

4. 在筛选器CUDA中创建一个CUDA源代码文件,kernel.cu

       我们直接把已经写好的矩阵相乘的程序kernel.cu复制到项目目录下,添加到CUDA筛选器中去。

       添加”--> “现有项”-->kernel.cu--> “添加”:

如何在MFC中调用CUDA

       kernel.cuint main()函数改为extern "C" int runtest(float* GPU, float* CPU),两个参数用来获得GPUCPU计算所使用的时间,单位为毫秒。

5. 右击项目-->“生成自定义”:

如何在MFC中调用CUDA

在弹出的窗口中勾选CUDA 5.0(.target,.props)。如果使用其他版本的CUDA,就勾选对应的版本:

如何在MFC中调用CUDA

点击“确定”。

6. 修改 kernel.cu的编译链接设置

       在解决方案资源管理器中右击kernel.cu文件-->“属性”,在弹出窗口中-->“常规”-->“项类型”的下拉列表中选择

 

如何在MFC中调用CUDA

       点击“应用后,“常规”下方会出现一个“CUDA C/C++”的设置,没有特殊需求,不需要修改,点击“确定”。

 

7.修改工程设置。

 

       工程设置需要修改“链接器”-->“输入”-->“附加依赖项”和“生成事件”-->“预先生成事件”-->“命令行”。需要设置的参数比较多,我们采用比较简单的方法。

 

       我们新建一个空的CUDA项目,在这个空CUDA项目的项目属性中找到“链接器”-->“输入”-->“附加依赖项”,把“附加依赖项”中所包含的项复制到我们的MFC项目中:

如何在MFC中调用CUDA

       按照同样的方法,设置“生成事件”-->“预先生成事件”-->“命令行”:

如何在MFC中调用CUDA

设置完成后,点击“确定”。

8.修改MFC文件,完成调用。

       我们需要在MFC中调用CUDA程序,显示出GPUCPU计算两个1024*1024矩阵相乘所消耗的时间。

       Matrix Multiplication_KahanMFCView.cpp中包含(include"CUDA_Transfer.h"

文件;在CMatrixMultiplication_KahanMFCView::OnDraw(CDC* pDC)中添加如下代码:

 

         float GPU;

         float CPU;

         run_cuda(&GPU, &CPU);

 

         CString strGPU,strCPU;

         strGPU.Format(_T("GPU:%f \n"),GPU);

         strCPU.Format(_T("CPU:%f \n"),CPU);

         pDC->TextOut(0,0,strGPU);

         pDC->TextOut(0,30,strCPU);

 

如图所示:

如何在MFC中调用CUDA

       然后重新生成解决方案,运行。

         计算要花费一些时间,需要等待,测试的时候可以把矩阵大小改小一些。因为把程序加到了OnDraw中,所以每当刷新窗口时候(例如调整窗口大小时),都会调用。由于计算耗时比较长,窗口看起来会像无响应一样,等计算完成就好了。

       运行的结果如下:

如何在MFC中调用CUDA

       在矩阵比较大的情况下,GPU的加速效果明显,GPU耗时只需要620ms,而CPU需要23438ms,要花费将近40倍的时间。

0 0