【发布时间】:2015-01-31 20:39:51
【问题描述】:
伙计们。
我正在 OpenCL 1.2 上开发一个序列比较应用程序,并在 AMD R9 280X GPU 中进行测试。以下是显卡信息:
DRIVER_VERSION: 1445.5 (VM)
Type: GPU
EXECUTION_CAPABILITIES: Kernel
GLOBAL_MEM_CACHE_TYPE: Read-Write (2)
CL_DEVICE_LOCAL_MEM_TYPE: Local (1)
SINGLE_FP_CONFIG: 0xbe
QUEUE_PROPERTIES: 0x2
VENDOR_ID: 4098
MAX_COMPUTE_UNITS: 32
MAX_WORK_ITEM_DIMENSIONS: 3
MAX_WORK_GROUP_SIZE: 256
PREFERRED_VECTOR_WIDTH_CHAR: 4
PREFERRED_VECTOR_WIDTH_SHORT: 2
PREFERRED_VECTOR_WIDTH_INT: 1
PREFERRED_VECTOR_WIDTH_LONG: 1
PREFERRED_VECTOR_WIDTH_FLOAT: 1
PREFERRED_VECTOR_WIDTH_DOUBLE: 1
MAX_CLOCK_FREQUENCY: 1020
ADDRESS_BITS: 32
MAX_MEM_ALLOC_SIZE: 1073741824
IMAGE_SUPPORT: 1
MAX_READ_IMAGE_ARGS: 128
MAX_WRITE_IMAGE_ARGS: 8
IMAGE2D_MAX_WIDTH: 16384
IMAGE2D_MAX_HEIGHT: 16384
IMAGE3D_MAX_WIDTH: 2048
IMAGE3D_MAX_HEIGHT: 2048
IMAGE3D_MAX_DEPTH: 2048
MAX_SAMPLERS: 16
MAX_PARAMETER_SIZE: 1024
MEM_BASE_ADDR_ALIGN: 2048
MIN_DATA_TYPE_ALIGN_SIZE: 128
GLOBAL_MEM_CACHELINE_SIZE: 64
GLOBAL_MEM_CACHE_SIZE: 16384
GLOBAL_MEM_SIZE: 2893021184
MAX_CONSTANT_BUFFER_SIZE: 65536
MAX_CONSTANT_ARGS: 8
LOCAL_MEM_SIZE: 32768
ERROR_CORRECTION_SUPPORT: 0
PROFILING_TIMER_RESOLUTION: 1
ENDIAN_LITTLE: 1
AVAILABLE: 1
COMPILER_AVAILABLE: 1
MAX_WORK_GROUP_SIZES: 256 256 256
程序是正确的并且产生了正确的结果(它也可以在其他 CPU 和 GPU 处理器上运行),但是性能很差。在我看来,OpenCL 并没有使用所有可用的内核。相同的代码在 Nvidia GTX 680 卡上运行速度提高 50 倍。
代码有点复杂,所以我只发布主机代码,一旦 OpenCL 代码正确执行。
err = 0;
err = clSetKernelArg(kernel2, 0, sizeof(i0), &i0);
err |= clSetKernelArg(kernel2, 1, sizeof(i1), &i1);
err |= clSetKernelArg(kernel2, 2, sizeof(step), &step);
err |= clSetKernelArg(kernel2, 3, sizeof(cutBlock), &cutBlock);
err |= clSetKernelArg(kernel2, 4, sizeof(cl_mem), (void*) &op->d_blockResult);
err |= clSetKernelArg(kernel2, 5, sizeof(cl_mem), (void*) &op->d_busH);
err |= clSetKernelArg(kernel2, 6, sizeof(cl_mem), (void*) &op->d_extraH);
err |= clSetKernelArg(kernel2, 7, sizeof(cl_mem), (void*) &op->d_busV_h);
err |= clSetKernelArg(kernel2, 8, sizeof(cl_mem), (void*) &op->d_busV_e);
err |= clSetKernelArg(kernel2, 9, sizeof(cl_mem), (void*) &op->d_busV_o);
err |= clSetKernelArg(kernel2, 10, sizeof(cl_mem), (void*) &op->d_split_m);
err |= clSetKernelArg(kernel2, 11, sizeof(cl_mem), (void*) &op->t_seq0);
err |= clSetKernelArg(kernel2, 12, sizeof(cl_mem), (void*) &op->t_seq1);
if (err != CL_SUCCESS)
exit(0);
global = blocks * threads;
local = threads;
err = clGetKernelWorkGroupInfo(kernel2, device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(max_work_groups), &max_work_groups, NULL);
if (err != CL_SUCCESS)
exit(0);
err = clEnqueueNDRangeKernel(commands, kernel2, 1, NULL, &global, &local, 0, NULL, &k_event);
if (err != CL_SUCCESS)
exit(0);
err = clWaitForEvents(1,&k_event);
err = clReleaseEvent(k_event);
在典型的执行中,global=4096 和 local=64,所以工作量大于 GPU 核心数。
OpenCL 有什么理由不使用所有可用的内核?会不会是驱动错误?
提前致谢。
马可
【问题讨论】:
-
你怎么知道它没有在所有内核上运行?
-
所以你真正关心的是“性能很差”。您是否对内核进行了概要分析以查看其中实际发生的情况?
-
嗨,talonmies 和 void_ptr。首先,感谢您的帮助。
-
我还无法分析应用程序,但这里有一些额外的信息。应用程序比较两个巨大的序列(超过 1M 的字符)内核使用 THREADS=128 编译。该代码也在 8 核 CPUS 中运行。在 AMD 280X GPU 中,应用程序(完全相同的代码)的执行速度仅比 CPU 快 2 倍。在两个 Nvidia GPU 卡(GTX 580 和 GTX 680)中,应用程序的运行速度至少快 50 倍。在执行过程中,应用程序会打印部分结果:在 Nvidia GPU 中,每一步都有超过 200 个单元块是进程;在 AMD GPU 中,只有 8 个块。有什么想法吗?
-
如果没有看到内核代码,也没有分析结果,就无法判断性能如何。我建议你添加这些细节。您还提到了打印部分结果 - 如果发生在内核代码中,它会影响您的性能。