首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCL (aparapi)在Radeon上的简单还原慢

OpenCL (aparapi)在Radeon上的简单还原慢
EN

Stack Overflow用户
提问于 2016-10-11 14:59:53
回答 2查看 226关注 0票数 0

我试图在OpenCL中的一个大的双数组上编写一个简单的缩减(在本例中是和)。我看过在线教程,发现这基本上就是解决问题的方法:

代码语言:javascript
复制
#pragma OPENCL EXTENSION cl_khr_fp64 : enable

typedef struct This_s{
   __global double *nums;
   int nums__javaArrayLength;
   __local double *buffer;
   __global double *res;
   int passid;
}This;
int get_pass_id(This *this){
   return this->passid;
}
__kernel void run(
   __global double *nums, 
   int nums__javaArrayLength, 
   __local double *buffer, 
   __global double *res, 
   int passid
){
   This thisStruct;
   This* this=&thisStruct;
   this->nums = nums;
   this->nums__javaArrayLength = nums__javaArrayLength;
   this->buffer = buffer;
   this->res = res;
   this->passid = passid;
   {
      int tid = get_local_id(0);
      int i = (get_group_id(0) * get_local_size(0)) + get_local_id(0);
      int gridSize = get_local_size(0) * get_num_groups(0);
      int n = this->nums__javaArrayLength;
      double cur = 0.0;
      for (; i<n; i = i + gridSize){
         cur = cur + this->nums[i];
      }
      this->buffer[tid]  = cur;
      barrier(CLK_LOCAL_MEM_FENCE);
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<32){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 32)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<16){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 16)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<8){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 8)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<4){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 4)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<2){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 2)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid<1){
         this->buffer[tid]  = this->buffer[tid] + this->buffer[(tid + 1)];
      }
      barrier(CLK_LOCAL_MEM_FENCE);
      if (tid==0){
         this->res[get_group_id(0)]  = this->buffer[0];
      }
      return;
   }
}

如果您想知道奇怪的this,那是一个(不幸的是必要的) aparapi的工件,我用它将OpenCL转换成OpenCL。

我的内核产生了正确的结果,并且在相当强大的Nvidia硬件上,它比Java中的顺序和快大约10倍。然而,在Radeon 280上,它的性能与简单的R9代码相当。

我已经用CodeXL对内核进行了剖析。它告诉我,MemUnitBusy仅占6%。为什么这么低?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-14 10:15:18

事实证明,OpenCL并不是(直接的)错误,但是aparapis缓冲区管理是错误的。

我在没有aparapi的情况下尝试了完全相同的内核,而且性能很好。一旦我使用CL_MEM_USE_HOST_PTR,它就会变得很糟糕,遗憾的是,这是使用aparapi时唯一的选择。即使在几次“热身”运行之后,AMD似乎也没有将主机内存复制到设备上。

票数 0
EN

Stack Overflow用户

发布于 2016-12-29 13:04:34

您可能想要考虑迁移到aparapi.com中更活跃的项目。它包括对bug的几个修复,以及与前面链接的旧库相比的许多额外特性和性能增强。它还位于maven中心,大约有十几个版本。因此,它更容易使用。新的Github存储库在这里

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39980333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档