【发布时间】:2012-10-02 13:05:34
【问题描述】:
我正在研究 OpenCL,与我预期的运行方式相比,我有点困惑为什么这个内核运行得这么慢。这是内核:
__kernel void copy(
const __global char* pSrc,
__global __write_only char* pDst,
int length)
{
const int tid = get_global_id(0);
if(tid < length) {
pDst[tid] = pSrc[tid];
}
}
我通过以下方式创建了缓冲区:
char* out = new char[2048*2048];
cl::Buffer(
context,
CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY,
length,
out);
输入缓冲区同上,除了我已将 in 指针初始化为随机值。最后,我这样运行内核:
cl::Event event;
queue.enqueueNDRangeKernel(
kernel,
cl::NullRange,
cl::NDRange(length),
cl::NDRange(1),
NULL,
&event);
event.wait();
平均而言,时间约为 75 毫秒,计算公式为:
cl_ulong startTime = event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
cl_ulong endTime = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
std::cout << (endTime - startTime) * SECONDS_PER_NANO / SECONDS_PER_MILLI << "\n";
我运行的是带有 Intel i5-3450 芯片(Sandy Bridge 架构)的 Windows 7。相比之下,进行复制的“直接”方式只需不到 5 毫秒。我不认为 event.getProfilingInfo 包括主机和设备之间的通信时间。想法?
编辑:
在 ananthonline 的建议下,我将内核更改为使用 float4s 而不是 chars,这将平均运行时间降低到大约 50 毫秒。仍然没有我希望的那么快,但有所改善。谢谢 ananthonline!
【问题讨论】:
-
这是什么实现?英特尔 OpenCL 实施?您是否尝试过使用 4 浮点数组的相同内核?这可能是一种更好的内存访问模式。
-
是的,英特尔 OpenCL 实施。我还没有尝试过 4-floats,这是一个好主意。我会调查的。
-
出于好奇,
clEnqueueCopyBuffer的表现如何?这就是你所说的“直接”吗? -
@willglynn 好多了。分析信息将时间报告为大约 2 毫秒。在 QueryPerformanceCounters 中包装对 event.wait() 的调用会报告时间稍高一些,大约 8 毫秒,但当然这包括等待调用本身的开销。
-
@willglynn 但我所说的“直接”是一个 memcopy 调用。我知道,这有点像苹果到橘子,但它至少提供了某种基线。
标签: performance opencl gpgpu