Parallel processing OpenCL:选择最佳全局工作大小值

Parallel processing OpenCL:选择最佳全局工作大小值,parallel-processing,opencl,Parallel Processing,Opencl,假设我想添加两个大小各为1亿的向量,如何选择最佳的global\u work\u size 它必须是global\u work\u size=100e6,还是 使用尺寸为10e6 x 10e6的2D ND范围是否更好,或者 还有其他策略吗 显然,我的GPU卡远没有同时提供1亿个工作项,甚至处理元素 更具体地说,global\u work\u size通常应该等于要并行处理的数据数量吗 感谢您的案例,您应该专注于为您的设备选择最佳的工作组大小,并让每个工作项处理多个元素。让全局工作项数等于要处

假设我想添加两个大小各为1亿的向量,如何选择最佳的
global\u work\u size

  • 它必须是
    global\u work\u size=100e6
    ,还是
  • 使用尺寸为10e6 x 10e6的2D ND范围是否更好,或者
  • 还有其他策略吗
显然,我的GPU卡远没有同时提供1亿个工作项,甚至处理元素

更具体地说,
global\u work\u size
通常应该等于要并行处理的数据数量吗


感谢您的案例,您应该专注于为您的设备选择最佳的工作组大小,并让每个工作项处理多个元素。让全局工作项数等于要处理的元素数通常比较简单,但对于GPU来说,问题非常大,尤其是一些低端GPU

我怀疑2D范围会对你有所帮助,因为你的作品本质上是一维的

例如,使用组大小或256,其中每个工作项处理256个元素。一个小组将负责65536个元素。总数为1526组,包括390656个单独的工作项目

来自的简单内核可以正常工作。n仍然是元素的总数。工作项id和工作组id都未使用

__kernel void vecAdd(  __global double *a, __global double *b, __global double *c, const unsigned int n)
{                                           
  //Get our global thread ID and global size
  int gid = get_global_id(0);              
  int gsize = get_global_size(0);              

  //check vs n using for-loop condition
  for(int i=gid; i<n; i+= gsize){
    c[i] = a[i] + b[i];              
  }
}
\uuuuuu内核void vecAdd(\uuuuu全局双精度*a、\uuuu全局双精度*b、\uuuu全局双精度*c、常量无符号整数n)
{                                           
//获取全局线程ID和全局大小
int gid=获取全局id(0);
int gsize=获取全局大小(0);
//使用for循环条件检查vs n
for(int i=gid;i n){
endIndex=n;
}

对于(int i=startIndex+itemId;ii在您的情况下,您应该专注于为您的设备选择一个最佳的工作组大小,并让每个工作项处理多个元素。让全局工作项数等于要处理的元素数通常比较简单,但您的问题对于GPU来说非常大,尤其是一些低端GPUGPU

我怀疑2D范围会对你有所帮助,因为你的作品本质上是一维的

例如,使用组大小或256,其中每个工作项处理256个元素。然后,一个组将负责65536个元素。总共是1526个组,由390656个单独的工作项组成

来自的简单内核可以正常工作。n仍然是元素的总数。工作项id和工作组id都未使用

__kernel void vecAdd(  __global double *a, __global double *b, __global double *c, const unsigned int n)
{                                           
  //Get our global thread ID and global size
  int gid = get_global_id(0);              
  int gsize = get_global_size(0);              

  //check vs n using for-loop condition
  for(int i=gid; i<n; i+= gsize){
    c[i] = a[i] + b[i];              
  }
}
\uuuuuu内核void vecAdd(\uuuuu全局双精度*a、\uuuu全局双精度*b、\uuuu全局双精度*c、常量无符号整数n)
{                                           
//获取全局线程ID和全局大小
int gid=获取全局id(0);
int gsize=获取全局大小(0);
//使用for循环条件检查vs n
for(int i=gid;i n){
endIndex=n;
}

对于(int i=startIndex+itemId;ii在您的情况下,您应该专注于为您的设备选择一个最佳的工作组大小,并让每个工作项处理多个元素。让全局工作项数等于要处理的元素数通常比较简单,但您的问题对于GPU来说非常大,尤其是一些低端GPUGPU

我怀疑2D范围会对你有所帮助,因为你的作品本质上是一维的

例如,使用组大小或256,其中每个工作项处理256个元素。然后,一个组将负责65536个元素。总共是1526个组,由390656个单独的工作项组成

来自的简单内核可以正常工作。n仍然是元素的总数。工作项id和工作组id都未使用

__kernel void vecAdd(  __global double *a, __global double *b, __global double *c, const unsigned int n)
{                                           
  //Get our global thread ID and global size
  int gid = get_global_id(0);              
  int gsize = get_global_size(0);              

  //check vs n using for-loop condition
  for(int i=gid; i<n; i+= gsize){
    c[i] = a[i] + b[i];              
  }
}
\uuuuuu内核void vecAdd(\uuuuu全局双精度*a、\uuuu全局双精度*b、\uuuu全局双精度*c、常量无符号整数n)
{                                           
//获取全局线程ID和全局大小
int gid=获取全局id(0);
int gsize=获取全局大小(0);
//使用for循环条件检查vs n
for(int i=gid;i n){
endIndex=n;
}

对于(int i=startIndex+itemId;ii在您的情况下,您应该专注于为您的设备选择一个最佳的工作组大小,并让每个工作项处理多个元素。让全局工作项数等于要处理的元素数通常比较简单,但您的问题对于GPU来说非常大,尤其是一些低端GPUGPU

我怀疑2D范围会对你有所帮助,因为你的作品本质上是一维的

例如,使用组大小或256,其中每个工作项处理256个元素。然后,一个组将负责65536个元素。总共是1526个组,由390656个单独的工作项组成

来自的简单内核可以正常工作。n仍然是元素的总数。工作项id和工作组id都未使用

__kernel void vecAdd(  __global double *a, __global double *b, __global double *c, const unsigned int n)
{                                           
  //Get our global thread ID and global size
  int gid = get_global_id(0);              
  int gsize = get_global_size(0);              

  //check vs n using for-loop condition
  for(int i=gid; i<n; i+= gsize){
    c[i] = a[i] + b[i];              
  }
}
\uuuuuu内核void vecAdd(\uuuuu全局双精度*a、\uuuu全局双精度*b、\uuuu全局双精度*c、常量无符号整数n)
{                                           
//获取全局线程ID和全局大小
int gid=获取全局id(0);
int gsize=获取全局大小(0);
//使用for循环条件检查vs n
for(int i=gid;i n){
endIndex=n;
}

对于(int i=startIndex+itemId;i除非我有不同的设备,可以将工作分成不同的部分,否则我只需一次将整个线性范围排队。OpenCL驱动程序将串行地处理块,这些块可以比我们更有效地同时安装在硬件中。此外,他们也有可能以获得最佳内存的方式进行处理我的行为也是如此

关于选择2D vs 1D范围,我不会将我的问题更改为2D,只是为了将一个较小的范围排队。但是,如果你的问题本质上是二维的(例如2D图像或2D矩阵),那么用这种方式表示它是有意义的

编辑:mfa关于t内循环的观点