当前位置: 首页 > 编程笔记 >

cuda 用CUDA对两个数组求和

王君墨
2023-03-14
本文向大家介绍cuda 用CUDA对两个数组求和,包括了cuda 用CUDA对两个数组求和的使用技巧和注意事项,需要的朋友参考一下

示例

本示例说明了如何创建一个简单的程序,该程序将int使用CUDA对两个数组求和。

CUDA程序是异构的,由在CPU和GPU上运行的部分组成。

利用CUDA的程序的主要部分类似于CPU程序,包括

  • 为将在GPU上使用的数据分配内存

  • 数据从主机内存复制到GPU内存

  • 调用内核函数来处理数据

  • 将结果复制到CPU内存

要分配设备内存,我们使用cudaMalloc功能。可以在设备和主机之间复制数据cudaMemcpy。的最后一个参数cudaMemcpy指定复制操作的方向。有5种可能的类型:

  • cudaMemcpyHostToHost -主机->主机

  • cudaMemcpyHostToDevice -主机->设备

  • cudaMemcpyDeviceToHost -设备->主机

  • cudaMemcpyDeviceToDevice -设备->设备

  • cudaMemcpyDefault -基于默认的统一虚拟地址空间

接下来,调用内核函数。三重人字形之间的信息是执行配置,该配置决定了多少个设备线程并行执行内核。第一个数字(2例如)指定块数,第二个(例如)指定块(size + 1) / 2中的线程数。请注意,在此示例中,我们将大小加1,以便我们请求一个额外的线程,而不是让一个线程负责两个元素。

由于内核调用是异步函数,因此它cudaDeviceSynchronize被调用以等待执行完成。结果数组将复制到主机内存,并使用释放设备上分配的所有内存cudaFree。

将函数定义为内核  __global__声明说明符。每个线程都会调用此函数。如果希望每个线程处理结果数组的元素,则需要一种区分和标识每个线程的方法。CUDA定义变量blockDim,blockIdx和threadIdx。预定义变量blockDim包含内核启动的第二个执行配置参数中指定的每个线程块的尺寸。预定义的变量threadIdx和blockIdx包含的线程的它的线程块内的网格内的索引和线程块,分别。注意,由于请求的线程数可能比数组中的元素多,因此我们需要传递信息size以确保不访问数组末尾。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

__global__ void addKernel(int* c, const int* a, const int* b, int size) {
    int i =blockIdx.x*blockDim.x+ threadIdx.x;
    if (i < size) {
        c[i] = a[i] + b[i];
    }
}

// 使用CUDA并行添加向量的辅助函数。
void addWithCuda(int* c, const int* a, const int* b, int size) {
    int* dev_a = nullptr;
    int* dev_b = nullptr;
    int* dev_c = nullptr;

    // 为三个向量分配GPU缓冲区(两个输入,一个输出)
    cudaMalloc((void**)&dev_c, size * sizeof(int));
    cudaMalloc((void**)&dev_a, size * sizeof(int));
    cudaMalloc((void**)&dev_b, size * sizeof(int));

    // 将输入向量从主机内存复制到GPU缓冲区。
    cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);

    // 在GPU上启动内核,每个元素只有一个线程。
    // 2是计算块数,(size + 1)/ 2是一个块中的线程数
    addKernel<<<2, (size + 1) / 2>>>(dev_c, dev_a, dev_b, size);
    
    // cudaDeviceSynchronize等待内核完成,然后返回
    // 启动过程中遇到的任何错误。
    cudaDeviceSynchronize();

    // 将输出向量从GPU缓冲区复制到主机内存。
    cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);

    cudaFree(dev_c);
    cudaFree(dev_a);
    cudaFree(dev_b);
}

int main(int argc, char** argv) {
    const int arraySize = 5;
    const int a[arraySize] = {  1,  2,  3,  4,  5 };
    const int b[arraySize] = { 10, 20, 30, 40, 50 };
    int c[arraySize] = { 0 };

    addWithCuda(c, a, b, arraySize);

    printf("{1, 2, 3, 4, 5} + {10, 20, 30, 40, 50} = {%d, %d, %d, %d, %d}\n", c[0], c[1], c[2], c[3], c[4]);

    cudaDeviceReset();

    return 0;
}
           

 类似资料:
  • CUDA 工具包是一种针对支持CUDA功能的GPU(图形处理器)的C语言开发环境。CUDA 开发环境包括: nvcc C语言编译器 适用于GPU(图形处理器)的CUDA FFT和BLAS库 分析器 适用于GPU(图形处理器)的gdb调试器(在2008年3月推出alpha版) CUDA运行时(CUDA runtime)驱动程序(目前在标准的NVIDIA GPU驱动中也提供) CUDA编程手册 CUD

  • 本文向大家介绍python中cuda()作用,两个Tensor,一个加了cuda(),一个没加,相加后很怎样?相关面试题,主要包含被问及python中cuda()作用,两个Tensor,一个加了cuda(),一个没加,相加后很怎样?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: cuda()将操作对象放在GPU内存中,加了cuda()的Tensor放在GPU内存中而没加的Tensor放在C

  • 译者:片刻 torch.cuda 用于设置和运行 CUDA 操作。它会跟踪当前选定的GPU,并且默认情况下会在该设备上创建您分配的所有 CUDA tensors。可以使用 torch.cuda.device 上下文管理器更改所选设备。 但是,一旦分配了 tensor,就可以对其进行操作而不管所选择的设备如何,结果将始终与 tensor 放在同一设备上。 默认情况下不允许跨 GPU 操作,除了 co

  • torch.cuda会记录当前选择的GPU,并且分配的所有CUDA张量将在上面创建。可以使用torch.cuda.device上下文管理器更改所选设备。 但是,一旦张量被分配,您可以直接对其进行操作,而不考虑所选择的设备,结果将始终放在与张量相同的设备上。 默认情况下,不支持跨GPU操作,唯一的例外是copy_()。 除非启用对等存储器访问,否则对分布不同设备上的张量任何启动操作的尝试都将会引发错

  • 一个用于开发CUDA的VS(Visual Studio)向导。当你安装了 CUDA VS Wizard,你将会在你的Visual Studio已安装的模板目录中看到CUDAWinApp。然后很容易就在VS中创建一个新的CUDA项目。它能支持Windows32位和64位系统。

  • 我运行的是Arch Linux,并从存储库中安装了cuda sdk和cuda工具包。我已经编译了/opt/cudasdk/CUDALibraries中的库。 不,我运行make in /opt/cuda-sdk/C编译sdk示例,得到以下错误: Makefile本身似乎只包含文件/opt/cudasdk/C/common/common。mk,即: Echo$LD_LIBRARY_PATH的输出为空