我有两个几乎相同的 OpenCL 内核,我想计算它们在 GFLOPS 中的性能。内核 #1 是:
__kernel void Test41(__global float *data, __global float *rands, int index, int rand_max){
float16 temp;
int gid = get_global_id(0);
temp = data[gid];
temp = (float) rands[1] * temp;
temp = (float) rands[2] * temp;
temp = (float) rands[3] * temp;
temp = (float) rands[4] * temp;
.
.
.
temp = (float) rands[497] * temp;
temp = (float) rands[498] * temp;
temp = (float) rands[499] * temp;
data[gid] = temp.s0;
}
第二个内核是:
__kernel void Test42(__global float *data, __global float *rands, int index, int rand_max){
float16 temp[500];
int gid = get_global_id(0);
temp[0] = data[gid];
temp[1] = (float) rands[1] * temp[0];
temp[2] = (float) rands[2] * temp[1];
temp[3] = (float) rands[3] * temp[2];
temp[4] = (float) rands[4] * temp[3];
.
.
.
temp[497] = (float) rands[497] * temp[496];
temp[498] = (float) rands[498] * temp[497];
temp[499] = (float) rands[499] * temp[498];
data[gid] = temp[index].s0;
}
正如您在代码中看到的,我使用的流大小为 16。每个内核都有 500 行操作,其中每个内核只执行一个浮点操作。我还总共部署了大约 1048576 个内核,因此我将有大约 1048576 个工作项并行执行。
为了计算我所做的翻牌:
flops = #numWorkItems(1048576) * (500) * StreamSize(16) / timeTaken;
不幸的是,对于第一个内核,我得到了大约 1.4 TFLOP,但对于第二个内核,我得到了 38 GFLOP。我无法解释这个巨大的差距。使用 temp 向量而不是单个 temp 似乎很重要。似乎真正的应用程序大多像第二个内核。第一个内核对于真正的应用程序来说太简单了。
谁能帮助我了解这里到底发生了什么以及第二个内核性能如何达到第一个?一般来说,如果我要对我的设备进行基准测试,我是否应该期望看到接近理论值的性能?
PS 我知道我需要将 rands 复制到 __local 内存中,但现在让我们跳过它。