我遵循了“专业CUDA C编程”教科书中翘曲发散的示例(以下代码)。
__global__ void math_kernel1(float *c) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
float a, b;
a = b = 0.f;
if (tid % 2 == 0) {
a = 100.0f;
} else {
b = 200.0f;
}
c[tid] = a + b;
}
__global__ void math_kernel2(float *c) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
float a, b;
a = b = 0.f;
if ((tid / warpSize) % 2 == 0) {
a = 100.0f;
} else {
b = 200.0f;
}
c[tid] = a + b;
}
__global__ void math_kernel3(float *c) {
int tid = blockIdx.x * blockDim.x + threadIdx.x;
float a, b;
bool ipred = (tid % 2 == 0);
a = b = 0.f;
if (ipred) {
a = 100.0f;
}
if (!ipred) {
b = 200.0f;
}
c[tid] = a + b;
}
很显然(写在教科书上),math_kernel2
应该具有最佳的分支效率,math_kernel1
随后是,math_kernel3
的结果最差。但是,nvprof
报告给我的结果与教科书相矛盾。我使用CUDA 8.0在GTX 1080 Ti上对这些内核进行了基准测试(我还向-g -G
添加了编译器标志nvcc
至count
以禁用优化),并且报告了以下分支效率: