`

闵大荒之旅(四) ---- CUDA预热

 
阅读更多

上一回演示了使用OpenCV中集成的gpu部分进行gpu编程,实现hog+svm算法对行人进行检测,检测效果对比得出gpu运行时间要远比cpu运行时间小,更加具有实时性。但是直接使用OpenCV中的函数,显得过于呆板,灵活性较差,于是,为了将gpu运算牢牢掌握在自己手里,我选择CUDA编程,接下来,我简单的介绍一下gpu、cuda的一部分内容。

 

1.CPU是顺序处理;GPU是并行处理,并行计算将大大缩短时间;

2.CUDA是NVIDIA公司推出的语言风格与C语言很相似的一款通用架构,必须要在NVIDIA公司生产的显卡上使用;

3.CUDA虽然是对GPU并行计算的一个编程框架,但是并不代表这不涉及到CPU:CPU负责进行逻辑性强的事物处理和串行计算,GPU则专注于执行高度线程化的并行处理任务

4.Jetson TK1板子上并不只是有GPU图形处理器,还有一个CPU(好像是ARM内核的),话说并行计算并不是说光光靠GPU计算就完事了,这只是其中一个部分,最后数据还是要返回到CPU中做最后的处理,只是CPU将比较麻烦、计算量比较大的交给GPU来完成而已!

 

其他的内容我就不详细叙述了,以上几点是我觉得有必要好好了解的。接下来,就开始愉快地开启CUDA编程之旅吧。

先来一段入手程序:test.cu

#include <iostream>
#include <stdio.h>
#include "book.h"
__global__ void kernel(int a, int b, int *c)
{
    *c = a + b;
}
int main()
{
        int c;
        int *dev_c;
        HANDLE_ERROR(cudaMalloc((void**)&dev_c, sizeof(int)));
        kernel<<<1,1>>>(1, 1, dev_c);
        HANDLE_ERROR(cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost));    
        printf("1+1 = %d\n", c);
        cudaFree(dev_c);
        return 0;
}

 乍一看,其实跟C语言几乎没有什么差别,这里只有几个要明白的地方:

1.虽然这个程序看上去跟C语言相似,但是这可不是.C文件,而是.CU文件,可以这么帮助理解,若看到有“__global__”的就可以认定这是个.CU文件,也就是对GPU进行操作的文件;

 

2.头文件:前两个好说,都是大家认识的,而第三个头文件book.h实际上是书《GPU高性能编程CUDA实战》中所附带的头文件,具体下载地址:https://bitbucket.org/mrfright/cuda_by_example/src

 

3.cudaMalloc函数类似于C语言中的开辟内存空间,当我们在GPU内想要得到运行的结果,就要开辟相应的内存空间,否则程序将出错;当然,若是使用到了OpenCV中的GpuMat,那就可以不用写这行代码,因为GpuMat实际上就已经开辟了内存空间(可以理解为内部写好了cudaMalloc吧)

 

4.HANDLE_ERROR()这个函数是book.h中所写好的,旨在确定()内程序是否正确执行,若执行错误则抛出相应的错误(其实我觉得不加也行吧)

 

5.__global__ void kernel 实际上就是GPU的核函数,这里我们先介绍一下GPU内部的一些抽象结构:
                          
                     (图片资源来自:http://blog.csdn.net/augusdi/article/details/12439805

CPU我们称作Host,GPU我们称作Device;

GPU线程结构:

内核以线程网格(Grid)的形式组织,每个线程网格由若干个线程块(block)组成,而每个线程块又由若干个线程(thread)组成。实质上,内核(kernel)是以block为单位执行的,CUDA引入grid只是用来表示一系列可以被并行执行的block的集合,各block的集合。各block是并行执行的,block间无法通信,也没有执行顺序。

所以所以,在__global__声明的这个函数中,实际上就是GPU的内核执行函数,你要做的运算具体内容、具体实现方式都是在这里面完成的

 

6.kernel <<<1,1>>>(1, 1, dev_c);这句话大有名堂啊,实际上也就是调用了5中所说的内核函数,其中:

<<<1,1>>>表示开启了1个block、1个thread线程进行计算,更复杂的情况我将后面阐述;

 

7.cudaMemcpy(源数据, 目标数据, 数据长度, 流向)

cudaMemcpyDeviceToHost表示GPU向CPU传输数据

cudaMemcpyHostToDevice表示CPU想GPU传输数据

 

8.cudaFree表示释放内存,程序员都知道,这是避免溢出的必要手段!

 

运行结果:1 + 1 = 2

表示.CU文件运行成功,成功使用GPU开启线程对1+1进行计算,别看简单,但是打好基础是完成更复杂项目的基础;

 

再来一段代码:

#include "book.h"

#define N 10

__global__ void add(int *a, int *b, int *c)
{
    int tid = blockIdx.x;
    if(tid < N)
    {
        c[tid] = a[tid] + b[tid];
    }
} 


int main()
{
    int a[N], b[N], c[N];
        int *dev_a, *dev_b, *dev_c;
        HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(int)));
        HANDLE_ERROR(cudaMalloc((void**)&dev_b, N * sizeof(int)));
        HANDLE_ERROR(cudaMalloc((void**)&dev_c, N * sizeof(int)));
        for(int i = 0; i < N; i++)
        {
        a[i] = i;
                b[i] = i * i;
        }
        HANDLE_ERROR(cudaMemcpy(dev_a, a, N * sizeof(int), cudaMemcpyHostToDevice));
        HANDLE_ERROR(cudaMemcpy(dev_b, b, N * sizeof(int), cudaMemcpyHostToDevice));
        add<<<N, 1>>>( dev_a, dev_b, dev_c);    
        HANDLE_ERROR(cudaMemcpy(c, dev_c, N * sizeof(int), cudaMemcpyDeviceToHost));       
 
        //show result
        for (int i = 0; i < N; i++)
        {
        printf("%d + %d = %d\n", a[i], b[i], c[i]);    
    }

    cudaFree(dev_a);
    cudaFree(dev_b);
    cudaFree(dev_c);
    return 0;
}
这段代码相对来说复杂了一点,注意要点如下:
add<<<N, 1>>>相当于开启了10个block每个block一个线程进行运算,实际上也就是数组中的10个元素同时进行运算,那么如何才知道哪个block计算元素的哪个元素呢?
注意到int tid = blockIdx.x;这里我们获取到了block的ID!
因为大家都是执行的相同的指令代码,不同的只是自己的编号,所以,利用这一点,我们可以将数据分开并行运算!是不是很机智!具体内容:
threadIdx,顾名思义获取线程thread的ID索引;如果线程是一维的那么就取threadIdx.x,二维的还可以多取到一个值threadIdx.y,以此类推到三维threadIdx.z。
blockIdx,线程块的ID索引;同样有blockIdx.x,blockIdx.y,blockIdx.z。
blockDim,线程块的维度,同样有blockDim.x,blockDim.y,blockDim.z。
gridDim,线程格的维度,同样有gridDim.x,gridDim.y,gridDim.z。
对于一维的block,线程的threadID=threadIdx.x。
对于大小为(blockDim.x, blockDim.y)的 二维 block,线程threadID=threadIdx.x+threadIdx.y*blockDim.x。
对于大小为(blockDim.x, blockDim.y, blockDim.z)的 三维 block,线程的threadID=threadIdx.x+threadIdx.y*blockDim.x+threadIdx.z*blockDim.x*blockDim.y。
运行结果不用多说了!
ubuntu下编译指令:nvcc 文件名.cu -c -o 文件名
  • 大小: 188.8 KB
分享到:
评论

相关推荐

    闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU

    《闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU》这篇博文主要探讨了在计算机视觉领域中,OpenCV库的GPU加速与CPU执行的对比。OpenCV是一个广泛使用的开源计算机视觉和机器学习库,它支持多种平台,并且提供了...

    Linuxtiny-cuda-nn直接安装

    根据配套的文章命令,就可以轻松的在自己电脑上(服务器linux上)安装成功tiny-cuda-nn啦!!git不下来?没关系,我下载好啦!安装总是报错?没关系,我下载的这个是全套完整的!!跟着安装命令步骤来,准没错!芜湖...

    CUDA-Memcheck用户手册4.0中文版

    CUDA调试工具cuda-gdb,包含一个可以在CUDA中检测和调试内存错误的内存检查特性。该文档描述了这个名为cuda-memcheck的工具与它的功能。 NVIDIA用它强大的cuda-gdb硬件调试器简化了CUDA程序错误的调试。然而,每个...

    onnxruntime-win-x64-gpu-cuda12-1.18.0.zip

    这个“onnxruntime-win-x64-gpu-cuda12-1.18.0.zip”文件是针对Windows 64位平台的GPU优化版本,包含了ONNX Runtime的库文件以及必要的头文件,使得开发者能够在支持CUDA 12的NVIDIA GPU上加速模型推理。 首先,让...

    COLMAP-3.8-windows-cuda.zip

    《COLMAP-3.8-windows-cuda:开启三维重建之旅》 在计算机视觉领域,三维重建是一项关键的技术,它能够将二维图像转化为三维模型,从而为各种应用提供基础,如虚拟现实、自动驾驶、建筑建模等。COLMAP(Coordinate-...

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第四个

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第四个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第四个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 ...

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第一个

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第一个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第一个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 ...

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第三个

    cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第三个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 总共四个 这个是第三个cuda-11.2.0-460.27.04-linux.run cuda安装包 亲测可用 ...

    mmdeploy-0.8.0-windows-amd64-cuda10.2-tensorrt8.2.3.0.zip

    《mmdeploy-0.8.0:mmlab在Windows平台上的高效部署工具》 mmdeploy-0.8.0-windows-amd64-cuda10.2-...无论是学术研究还是工业应用,这款工具都能极大地简化模型的部署流程,提升推理效率,是开发者不可或缺的利器。

    nccl-local-repo-ubuntu2004-2.8.4-cuda11.1-1.0-1-amd64.zip

    标题中的"nccl-local-repo-ubuntu2004-2.8.4-cuda11.1-1.0-1-amd64.zip"指的是NVIDIA Collective Communication Library (NCCL) 的本地仓库包,专为Ubuntu 20.04操作系统设计,并且与CUDA 11.1版本兼容。NCCL是一个...

    cuda10.1-cuda11.0-cuda11.1各版本windows系统下载.zip

    百度网盘提供,包含以下三种版本的cuda toolkit和对应的cudnn版本,适合windows10系统。 cudnn-10.1-windows10-x64-v7.6.4.38.zip cuda_10.1.243_426.00_win10.exe cudnn-11.0-windows-x64-v8.0.4.30.zip cuda_...

    COLMAP-3.9.1-windows-no-cuda.zip

    **COLMAP:一款强大的三维重建软件** COLMAP(Coordinate-based Localized Multiple View Stereo)是一款开源的、基于坐标系的局部多视图立体...通过掌握COLMAP的基本操作和流程,您可以开启自己的三维视觉探索之旅。

    COLMAP-3.6-windows-cuda.zip

    《COLMAP-3.6-windows-cuda:开启三维重建之旅》 在计算机视觉领域,三维重建是一项关键的技术,它能够从多个二维图像中恢复出场景的三维几何信息。COLMAP,全称为“Comparative Camera Relocalization and Mapping...

    cuda-repo-rhel7-11-0-local-11.0.2_450.51.05-1.x86_64.txt

    cuda-repo-rhel7-11-0-local-11.0.2_450.51.05-1.x86_64

    cpyrit-cuda-0.4.0

    cpyrit-cuda-0.4.0

    cuda-12.0.1-windows-network.exe

    cuda-12.0.1-windows-network.exe

    COLMAP-3.7-windows-cuda11.6.zip

    标题 "COLMAP-3.7-windows-cuda11.6.zip" 暗示这是一个针对Windows操作系统的软件包,主要用于计算机视觉领域的三维重建工具——COLMAP。COLMAP是一款开源的多视图立体匹配和三维重建软件,广泛应用于摄影测量、...

    cudnn-windows-x86-64-8.9.3.28-cuda12-archive

    标题 "cudnn-windows-x86-64-8.9.3.28-cuda12-archive" 暗示了这是一个针对Windows操作系统、64位架构的NVIDIA CUDA深度学习库CuDNN的版本8.9.3.28,与CUDA 12版本兼容的归档文件。CuDNN(CUDA Deep Neural Network...

    cudnn-windows-x86-64-8.9.6.50-cuda12-archive.zip

    cudnn8.9.6适合windows x64 cuda12.x版本cudnn-windows-x86_64-8.9.6.50_cuda12-archive.zip

Global site tag (gtag.js) - Google Analytics