Parallel processing 在这个函数中,全局和本地工作大小是如何分布的?

Parallel processing 在这个函数中,全局和本地工作大小是如何分布的?,parallel-processing,opencl,Parallel Processing,Opencl,这是来自OpenCL编程的。 我对如何计算全局和局部工作规模感到困惑。 它们是根据图像大小计算的 图像大小为1920 x 1080(宽x高) 我假设全局工作大小[0]和全局工作大小[1]是图像上的网格 但是现在全球的工作规模是{1281088} 然后,本地工作大小[0]和本地工作大小[1]是全局工作大小上的网格。 本地工作大小为{128,32} 但总组数,num_groups=34,不是128 x 1088 设备上可用的最大工作组大小为4096 如何将映像分配到这样的全球和本地工作组大小 它们在

这是来自OpenCL编程的。 我对如何计算全局和局部工作规模感到困惑。 它们是根据图像大小计算的

图像大小为1920 x 1080(宽x高)

我假设全局工作大小[0]和全局工作大小[1]是图像上的网格

但是现在全球的工作规模是{1281088}

然后,本地工作大小[0]和本地工作大小[1]是全局工作大小上的网格。 本地工作大小为{128,32}

但总组数,num_groups=34,不是128 x 1088

设备上可用的最大工作组大小为4096

如何将映像分配到这样的全球和本地工作组大小

它们在以下函数中计算

    clGetKernelWorkGroupInfo(histogram_rgba_unorm8, device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL);
    {
        size_t  gsize[2];
        int     w;

        if (workgroup_size <= 256)
        {
            gsize[0] = 16;//workgroup_size is formed into row & col
            gsize[1] = workgroup_size / 16;
        }
        else if (workgroup_size <= 1024)
        {
            gsize[0] = workgroup_size / 16;
            gsize[1] = 16;
        }
        else
        {
            gsize[0] = workgroup_size / 32;
            gsize[1] = 32;
        }

        local_work_size[0] = gsize[0];
        local_work_size[1] = gsize[1];

        w = (image_width + num_pixels_per_work_item - 1) / num_pixels_per_work_item;//to include all pixels, num_pixels_per_work_item is added first
        global_work_size[0] = ((w + gsize[0] - 1) / gsize[0]);//col
        global_work_size[1] = ((image_height + gsize[1] - 1) / gsize[1]);//row

        num_groups = global_work_size[0] * global_work_size[1];    
        global_work_size[0] *= gsize[0];
        global_work_size[1] *= gsize[1];
    }    
    err = clEnqueueNDRangeKernel(queue, histogram_rgba_unorm8, 2, NULL, global_work_size, local_work_size, 0, NULL, NULL);
    if (err)
    {
        printf("clEnqueueNDRangeKernel() failed for histogram_rgba_unorm8 kernel. (%d)\n", err);
        return EXIT_FAILURE;
    } 
clGetKernelWorkGroupInfo(柱状图\u rgba\u unorm8,设备,clu内核\u工作\u组大小,sizeof(SIZE\u t)和工作组大小,NULL);
{
尺寸[2];
int w;

if(workgroup_size我看不出这里有什么神秘之处。如果你按照计算,值确实会如你所说的那样结束。(在我看来,小组规模并不是特别有效。)

  • 如果
    workgroup\u size
    确实是4096,那么
    gsize
    将按照
    else
    逻辑以
    {128,32}
    结束。(>1024)
  • w
    是宽列的数量,或覆盖整个宽度的最小工作项数量,对于1920的图像宽度为60。换句话说,我们需要绝对最小的60 x 1080个工作项来覆盖整个图像
  • 接下来,计算组列和行的数量,并将其临时存储在
    global\u work\u size
    中。由于组宽度已设置为128,60的
    w
    意味着我们将得到一列组(这似乎是在浪费资源,每个组中的128个工作项中有一半以上不会做任何事情)组行数仅为
    image\u height
    除以
    gsize[1]
    (32)并向上取整。(33.75->34)
  • 现在可以通过乘以网格来确定组的总数:
    num\u groups=global\u work\u size[0]*global\u work\u size[1]
  • 为了获得每个维度中工作项的真实总数,现在将
    global\u work\u size
    的每个维度乘以该维度中的组大小。
    1,34
    乘以
    128,32
    得到
    1281088
  • 这实际上覆盖了4096 x 1088像素的区域,因此其中约53%是浪费。这主要是因为组维度的算法支持宽组,并且每个工作项工作在图像的32x1像素切片上。最好支持高工作组,以减少舍入量


    例如,如果我们反转
    gsize[0]
    gsize[1]
    ,在这种情况下,我们得到的组大小是
    {32128}
    ,给我们的全局工作大小是
    {641152}
    而且只有12%的损耗。如果总是选择尽可能大的组大小是否是一个好主意,这也值得检查;很可能不是,但我还没有详细研究内核的计算,更不用说运行任何测量,来判断是否是这样。

    我需要一些讨论。本地工作组大小定义为maxi最小值为128 x 32。它们被分配为本地工作大小[0]=gsize[0];本地工作大小[1]=gsize[1];图像大小为1920 x 1080,每个工作项的像素数=32。因此工作项的宽度要求为60,高度要求为34。然后全局工作大小表示其中有多少本地工作大小。因此全局工作大小[0]=((60+gsize[0]-1)/gsize[0])=1和全局工作大小[1]=((34+gsize[1]-1)/gsize[1])=2。但现在是全局工作大小[0]=1和全局工作大小[1]=34。还有,为什么要用gsize相乘?全局维度是该维度中的总工作项,而不是组数。OpenCL不会隐式地将全局值乘以本地值。例如,如果您想要3个组,每个组的大小为2,则必须将6作为全局值传递,将2作为本地值传递。对于OpenCL,1.x全局值必须是an本地大小的整数倍。感谢您的时间。我不知道,我没有编写该代码。我还想知道每个工作项的32x1像素选择是否明智。此外,使用最大可能的工作组大小可能也不理想。实际上,您需要在大范围内对各种不同的组合进行基准测试在选择分割工作的特定方式之前,请先检查硬件。请注意,64x64对于2050x1000这样的映像同样有害。