OpenCL基准-关于参数变化的建议

OpenCL基准-关于参数变化的建议,opencl,benchmarking,reduction,Opencl,Benchmarking,Reduction,我想在radeon HD 7970 Tahiti XT上执行有关OpenCL的两阶段求和减少的运行时基准测试(从此开始) 最初,我使用了第一个版本的代码,其中我没有使用第一个循环,该循环执行从大小为N的输入数组到大小为NworkItems的输出数组的缩减。下面是内核代码的第一个循环: int global_index = get_global_id(0); float accumulator = 0; // Loop sequentially over chunks of input

我想在radeon HD 7970 Tahiti XT上执行有关OpenCL的两阶段求和减少的运行时基准测试(从此开始)

最初,我使用了第一个版本的代码,其中我没有使用第一个循环,该循环执行从大小为
N
的输入数组到大小为
NworkItems
的输出数组的缩减。下面是内核代码的第一个循环:

  int global_index = get_global_id(0);
  float accumulator = 0;
  // Loop sequentially over chunks of input vector
  while (global_index < length) {
    float element = buffer[global_index];
    accumulator += element;
    global_index += get_global_size(0);
  }
int global\u index=get\u global\u id(0);
浮动累加器=0;
//在输入向量块上按顺序循环
while(全局_指数<长度){
浮动元素=缓冲区[全局索引];
累加器+=元件;
全局索引+=获取全局大小(0);
}
因此,在第一个版本中,我将运行时作为输入数组大小(等于线程总数)和不同大小的工作组的函数进行了测量。结果如下:

现在,我想做一个基准测试,使用上面的初始循环。但我不知道我必须改变哪些参数

从一开始,有人说AMD建议工作组大小为64的倍数(NVIDIA为32)

此外,从上一条评论开始,建议将工作组大小设置为:
工作组大小=(总线程数)/(计算单位)
。 在我的GPU卡上,我有32个计算单元

因此,我想得到一些建议,了解哪些参数会有兴趣改变,以便比较第二个版本(与第一个简化循环)中的运行时。例如,我可以为比率
(输入数组的N个大小)/(总N个工作项)
取不同的值,为
工作组大小
取固定值(参见上面的表达式)

或者相反,也就是说,我应该改变
工作组大小的值,并固定比率
(输入数组的N个大小)/(总NworkItems)


任何想法都是受欢迎的,谢谢

您应该对本地数据求和,而不是分散数据,以帮助内存传输(合并数据访问)。所以用这个来代替:

  int chunk_size = length/get_global_size(0)+(length%get_global_size(0) > 0); //Will give how many items each work item needs to process
  int global_index = get_group_id(0)*get_local_size(0)*chunk_size + get_local_id(0); //Start at this address for this work item
  float accumulator = 0;

  for(int i=0; i<chunk_size; i++)
    // Loop sequentially over chunks of input vector
    if (global_index < length) {
      float element = buffer[global_index];
      accumulator += element;
      global_index += get_local_size(0);
    }
  }
int chunk\u size=length/get\u global\u size(0)+(length%get\u global\u size(0)>0)//将给出每个工作项需要处理的项数
int global_index=get_group_id(0)*get_local_size(0)*chunk_size+get_local_id(0)//从此工作项的地址开始
浮动累加器=0;

对于(inti=0;iThanks)。如果我理解得很好,我只需要改变两个参数:首先是输入数组的“长度”,然后是“获取本地大小(0)”=“每个工作组的大小”。因此,我可以更改用于生成第一个基准的上图的相同参数。您的代码的问题是,工作项0正在从
缓冲区[]
读取分散的数据,这些数据由
全局大小()分隔
。根据工作项的大小,这可能会导致非常糟糕的内存模式。如果每个工作组在一小块缓冲区上工作,那么缓存效果会更好,甚至组中的所有工作项都可以共享缓存。对于给定的“工作组大小”,您是否建议我采用“总线程数=(工作组大小)*(计算单位)”用于我的基准测试(GPU卡上的计算单位=32,CPU上的计算单位=8)?