1

我是 OpenCL 的新手,对数组添加有一些问题我使用下面链接中提供的代码

http://code.google.com/p/opencl-book-sa​​mples/source/browse/#svn%2Ftrunk%2Fsrc%2FChapter_2%2FHelloWorld%253Fstate%253Dclose

我添加了一些部件来测量 GPU 的性能

clFinish(commandQueue);
        // Queue the kernel up for execution across the array
        cl_ulong start, end; cl_event  k_events;

        errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL,
                                        globalWorkSize, localWorkSize,
                                        0, NULL, &k_events);
         clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_START,  
                            sizeof(cl_ulong), &start, NULL); 
         clWaitForEvents(1 , &k_events);

    clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_END, 
                            sizeof(cl_ulong), &end, NULL); 
    clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_START,  
                            sizeof(cl_ulong), &start, NULL); 

    float GPUTime = (end - start);

这可以测量 CPU 时间

LARGE_INTEGER CPUstart, finish, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&CPUstart);

for (int i=0;i<ARRAY_SIZE;i++){

    result[i]=a[i]+b[i];
}

QueryPerformanceCounter(&finish);
double timeCPU=(finish.QuadPart - CPUstart.QuadPart) /((double)freq.QuadPart)/1000000000.0) ;

我遇到的第一个问题是数组大小;它不能超过 10000 ;如果我这样做;它只是崩溃。如何解决?

第二个问题是性能;GPU/CPU 比率范围太宽;从 13% 到 210% (ish)。为什么会发生这种情况,您能否提出修复建议?

编辑:我想出了第二个;延迟是由省电模式引起的;它将 core/mem 设置为远低于 default 。只需使用程序锁定它;并且性能稳定在 ~150-300 % (GPU/CPU)

好案例

GPU time :632667 nanosecs.
CPU time : 990023 nanosecs.
GPU/CPU ratio : 156.484 percent.

还有一个不好的:

GPU time :6.83267e+006 nanosecs.
CPU time : 1.00756e+006 nanosecs.
GPU/CPU ratio : 14.7462 percent.

任何想法将不胜感激。谢谢 :D

PS:CPU是酷睿i3-370M;显卡:HD5470。我在 Windows 7 上使用 VS2008

4

4 回答 4

1

这是一个很好的答案,可以帮助您了解达到极限的原因

C++ 中是否有最大数组长度限制?

如果您能找到一种在代码中创建内存管理的方法,这可能有助于缓解您的一些问题。

顺便说一句,我会寻找其他操作系统,例如可能能够帮助运行您的代码的 linux 环境。Windows 充满了占用内存的服务,可能是您的问题的一个因素。或者你可以得到更好的硬件。

于 2012-07-09T13:05:55.783 回答
1

一些东西:

如果您的本地工作量没有四舍五入到您的全局工作量,您最终可能会得到一小部分剩余部分。IE:本地大小为 100,全局大小为 1050 -> 50 额外。该位 IIRC 仍会得到处理。解决该问题的方法是 a) 确保均匀舍入,或 b) 检查内核中的保护变量,如果超出范围则中止。

其次,我注意到一些奇怪的clGetEventProfilingInfo地方,有时它会很准确,有时它会很不准确。我最终使用clFinish并对QueryPerformanceCounter我的 CL 代码进行了基准测试。

于 2012-07-09T16:08:37.587 回答
1

您的程序因更大的数组大小而崩溃的一个可能(也是最可能的)原因是由于main.cpp(原始代码中的第 274-276 行)中的以下代码:

float result[ARRAY_SIZE];
float a[ARRAY_SIZE];
float b[ARRAY_SIZE];

这些是自动数组,它们的空间在main函数的堆栈上分配。所需的总空间3*ARRAY_SIZE*sizeof(float)等于12*ARRAY_SIZE。Windows 上的默认堆栈大小为 1 MiB,这意味着ARRAY_SIZE最高可达 87380。这是给定默认堆栈大小的上限,并且由于堆栈也用于其他用途,因此实际值会略低一些。

您可以在 VS 项目属性的Linker -> System页面上增加堆栈大小。malloc()或者更好地使用或在堆上分配这些数组new[]

于 2012-07-10T07:45:49.490 回答
0

您可以使用 clGetDeviceInfo API 调用来确定您的 OpenCL 设备的两个关键参数

CL_DEVICE_MAX_MEM_ALLOC_SIZE 和 CL_DEVICE_GLOBAL_MEM_SIZE

http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetDeviceInfo.html

这些决定了您可以使用多少全局内存以及可以分配多少。

于 2012-07-09T19:12:10.123 回答