OpenCl程序不使用AMD 280X GPU中的所有可用内核

时间:2015-01-23 19:41:08

标签: opencl gpu

我正在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不使用所有可用内核的任何理由?它可能是一个驱动程序错误吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

 global=4096 and local=64, so the work size is greater than the number of GPU cores.

这还不够。你的gpu有2048个内核,但内核执行开销使执行本身相形见绌,因为​​每个内核只能工作两次。您需要至少8192,16384甚至1M的全局大小,具体取决于您在GPU上工作的算法。当内存单元也忙时,您需要保持这些内核忙碌。

Nvidia gpu可以拥有local = 1024,只需4个smx块即可完成整个工作。 (增加互通通信能力)。当工作量足够大时,你的卡可能会超负荷。

您是否将缓冲区上传-togpu和缓冲区下载-gpu时序保留在性能计算之外?

Any reason to OpenCL not to use all available cores? 

由于opencl没有告诉我们个人的核心使用情况,你只能说"它的确定"如果你的gpu加热量与gtx680相同,那么热源就是核心"半导体"

The same code runs 50X faster in a Nvidia GTX 680 card.

相同的代码,但CUDA? OpenCL的?互操作?你自己测试了吗?针对单核cpu或所有核心或所有核心与sse / avx?相同的驱动版本?同样的os?相同的环境?

你的算法是什么?如果那是矩阵乘法,需要更多的线程间通信,请使用local = 256(nvidia有1024)你使用的是异步拷贝吗?你的代码有任何假的递归?

相关问题