一、基于编程模型和执行模型的优化方法
1.选取合适的gridDim和blockDim
blockDim最好为32的整数倍:因为执行指令的基本单位为线程束,线程束内的所有线程统一执行广播下来的命令,而线程束的线程数量基本为32。当block被分到SM中去,其会被划分为多个线程束,若blockDim!=线程束内线程数整数倍,则会造成线程的浪费。
2.减少存在分支的if
因为线程束中的所有线程执行同一条的指令,若出现存在出现分支的if,即线程束内的部分线程符合if条件,部分符合else条件,因cuda编译不具备分支预测能力,则会在一个指令执行if,下一个指令执行else,两个指令中都有部分不符合条件的线程空闲,从而造成浪费,如下述代码所示:
__global__ void mathKernel1(float *c)
{
int tid = blockIdx.x* blockDim.x + threadIdx.x;
float a = 0.0;
float b = 0.0;
if (tid % 2 == 0)
{
a = 100.0f;
}
else
{
b = 200.0f;
}
c[tid] = a + b;
}
线程束内奇数线程(threadIdx.x为奇数)会执行else,偶数线程执行if,分化很严重。对此,我们可以更改if条件,使整个线程束内都符合if或else即可:
__global__ void mathKernel2(float *c)
{
int tid = blockIdx.x* blockDim.x + threadIdx.x;
float a = 0.0;