GPU高性能计算CUDA编程:将图像读入CPU端数组

GPU高性能计算CUDA编程:将图像读入CPU端数组

声明:本文不做商用

让我们看看用于存储初始的和处理后的CPU端图像数据的变量。代码6.1列出了main()函数的第一部分,下面列出的五个指针用于在CPU内存和GPU内存中存储图像:

  • 变量Thelmg是指向CPU内存的指针,在ReadBMPLin()函数中它由malloc()分配,用于存储在命令行中指定的图像数据(例如,dogL.bmp)。注意,变量Thelmg是一个指向CPU DRAM内存的指针。
  • 变量CopyImg是指向另一块CPU内存的指针,它的值由另一次的malloc()调用分配,用于存储原始图像的副本(该副本将被翻转,而原始图像则不会被改变)。请注意,到目前为止我们没有对GPU内存做任何事情。
  • 正如很快就会看到的,我们将用API来分配GPU内存。在需要时,通过调用名为cudaMalloc()的API来要求GPU内存管理器在GPU内存中为我们分配一段内存。因此,cudaMalloc()返回给我们的是指向GPUDRAM内存的指针,但是我们会把这个指针存储在一个CPU端变量GPUImg中。这可能会让人感到困惑,因为我们在CPU端变量中保存了一个GPU端的指针。实际上并不难理解,指针只不过是一些“数值”,或者更具体一点就是一个64位的整数。所以它们可以用与64位整数操作完全相同的方式进行存储、复制、相加或相减。什么时候需要在CPU端存储GPU端的指针呢?规则很简单:在CPU调用的API中出现的任何指针都必须在CPU端存储。现在,可以问自己一个问题:变量GPUImg会在CPU端使用吗?答案是肯定的,因为我们需要调用cudaMaloc()将数据从CPU端传输到GPU端。cudaMalloc()是CPU端函数,尽管它的功能与GPU有很大关系。所以,需要在CPU端变量中同时存储指向双方的指针。在GPU端我们肯定会使用同一个GPU端指针!但现在我们在主机(CPU)端复制了一个副本,所以CPU有机会在需要时访问它。如果不这么做,CPU将永远无法访问它,并且无法启动与该指针有关的GPU数据传输。
  • 另外两个GPU端指针GPUCopyImg和GPUResult的情况也差不多。它们是指向GPU内存的指针,其中,最终的“翻转”图像存储在GPUResult中,GPUCopyImg是GPU代码运行时所需的临时变量。这两个变量是CPU端变量,存储调用cudaMalloc()后获得的指针。

在每个CUDA程序中会有几个#include<文件路径>语句,分别是<cudaruntime.h>、<cuda.h>和 < device launch parameters.h >,以允许我们使用Nvidia的API。这些 API,例如 cudaMalloc(),是CPU和GPU端之间的桥梁。Nvidia的工程师开发了它们,让你能在CPU 和 GPU之间传输数据而不用关心具体的细节。参见【0voice C++】
请注意在这里定义的数据类型。ul、uch和ui分别表示 unsigned long、unsigned char 和unsignedint。这些类型的数据会经常使用,将它们定义为用户自定义的类型可以使代码更加清晰,减少代码中的混乱。存放文件名的变量是InputFileName和OutputFileName,它们的值都来自于命令行参数。变量ProgName被硬编码到程序中用于输出报告。

#include <cuda.h>
typedef unsigned char uch;
typedef unsigned long ul;
typedef unsigned int ui;

uch *TheImg, *CopyImg;                // CPU端图像数据指针
uch *GPUImg, *GPUCopyImg, *GPUResult; // GPU端图像数据指针
...
int main(int argc,char **argv)
{
    char InputFileName[255], OutputFileName[255], ProgName[255];
    ...
    strcpy(ProgName, "imflipG");
    switch(argc){
        case 5: ThrPerBlk=atoi(argv[4]);
        case 4: Flip = toupper(argv[3][0]);
        case 3: strcpy(InputFileName,argv[1]);
            strcpy(OutputFileName,argv[2]);
            break ;
        default: printf("\n\nUsage:%sInputFilename utp..");
            ...
    }
    ...
    TheImg = ReadBMPlin(InputFileName); // 读入图像
    CopyImg = (uch *)malloC(IMAGESIZE); // 为复制图像分配空间
    ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值