【发布时间】:2015-03-23 20:38:18
【问题描述】:
我读到了 OpenCL 中的全局内存优化。在其中一张幻灯片中,使用了一个非常简单的内核(如下)来演示内存合并的重要性。
__kernel void measure(__global float* idata, __global float* odata, int offset) {
int xid = get_global_id(0) + offset;
odata[xid] = idata[xid];
}
请看下面我测量内核运行时间的代码
ret = clFinish(command_queue);
size_t local_item_size = MAX_THREADS;
size_t global_item_size = INPUTSIZE;
struct timeval t0,t1;
gettimeofday(&t0, 0 );
//ret = clFinish(command_queue);
ret = clEnqueueNDRangeKernel(command_queue, measure, 1, NULL,
&global_item_size, &local_item_size, 0, NULL, NULL);
ret = clFlush(command_queue);
ret = clFinish(command_queue);
gettimeofday(&t1,0);
double elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + (t1.tv_usec-t0.tv_usec);
printf("time taken = %lf microseconds\n", elapsed);
我传输了大约 0.5 GB 的数据:
#define INPUTSIZE 1024 * 1024 * 128
int main (int argc, char *argv[])
{
int offset = atoi(argv[1]);
float* input = (float*) malloc(sizeof(float) * INPUTSIZE);
现在,结果有点随机。偏移量 = 0,我得到的时间低至 21 微秒。偏移量 = 1 时,我得到的时间范围在 53 到 24400 微秒之间。
谁能告诉我发生了什么事。我认为 offset=0 将是最快的,因为所有线程都将访问连续的位置,因此将发生最少数量的内存事务。
【问题讨论】:
-
您是否正在检查来自
clEnqueueNDRangeKernel和clFinish函数的错误代码? 21 微秒对于 500MB 的传输来说太低了,所以也许该函数实际上只是未能正确执行。