原文连接html
系列文章:git
-code
、-arch
、-gencode
选项在介绍编码相关内容以前,一个更重要的话题是什么类型的问题适合用GPU进行解决。程序员
GPU于CPU相比,有着惊人的核数、运算单元及内存带宽。对于给定问题,若是有办法把它分解为多个独立的子问题并行解决,那么GPU颇有可能提供比CPU更好的性能。所谓“独立”,指的是所分解的子问题知足:github
矩阵相乘就是一个很好的例子,对矩阵相乘结果中各个元素的计算之间没有任何依赖关系,可以很好地经过GPU进行并行。固然对于一些问题,可能没办法马上想出并行的办法,可是却存在可高效并行的问题分解办法,比方说:编程
(思考题)数组
对于手头的问题,若是可以顺利对问题进行分解,那么就有可能利用GPU提供的硬件特性及编程模型对其进行高效解决。bash
if (threadIdx.x % 2 == 0) {
// Some work
} else {
// Other work
}
复制代码
说点别的异步
32个thread组成的调度单元为何叫warp?缘由是thread有线的意思,而warp是织布机相关的一个把多个thread固定注的装置,因而就取了这个比喻:
ide
就像写CPU代码时会受到CPU核数、内存空间、访存速度的限制同样,GPU编程模型里也须要留意相关的资源限制:函数
CUDA编程中的常见流程是:
Cuda样例代码中的vectorAdd
完成的任务是对长为numElements
的两个数组h_A
、h_B
进行对应元素加合,并将结果存入h_C
中。接下来咱们以vectorAdd
为例,说明这一流程:
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
复制代码
__global__ void
vectorAdd(const float *A, const float *B, float *C, int numElements)
{
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements)
{
C[i] = A[i] + B[i];
}
}
复制代码
作的事情就是每一个thread负责根据本身所在的thread block及threadIdx计算出本身所应处理的数组下标,并对这一下标对应的元素完成一次加合计算。
<<<blocksPerGrid, threadsPerBlock>>>
指定了thread block数量及每一个block中的thread数量。vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
复制代码
cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
复制代码
一个cuda程序最重要的部分就完成了。完整代码中还包含了内存的分配、cuda调用的错误检查等内容,完整代码可见cuda安装目录下的samples/0_Simple/vectorAdd
。