我有两个几乎相同的OpenCL内核,我想用GFLOPS来计算它们的性能。内核#1:两个几乎相同的OpenCL内核之间的性能差距
__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 TFLOPs的,但对于第二个内核,我得到38个GFLOPS。我无法解释这个巨大的差距。使用一个温度矢量而不是单个温度似乎是一个巨大的交易。也似乎真正的应用程序大多像第二个内核。第一个内核对于真正的应用来说太简单了。
任何人都可以帮助我理解这里究竟发生了什么,以及第二个内核性能如何能够达到第一个?一般来说,如果我要对我的设备进行基准测试,我希望看到性能接近理论值吗?
P.S.我知道我需要将rands复制到__local内存中,但现在让我们跳过。
在第二个内核中有大量寄存器被分配给500个float16值的数组,所以很可能内核占用率下降导致内核运行缓慢。 – sgarizvi
500 * 16 * 4 = 32kB仅适用于单线程。由于内存使用情况,即使每个工作组的单个工作项目也会很慢。 –
每个工作项目的合理内存使用量是多少?我只是想在设计我的基准时有更好的把握。 – saman