C++ 如何避免opencl中的浮动原子外接程序

C++ 如何避免opencl中的浮动原子外接程序,c++,parallel-processing,opencl,gpgpu,C++,Parallel Processing,Opencl,Gpgpu,我需要在opencl中解析稀疏矩阵向量乘法,但是我在de内核完成时的时间非常慢。我认为慢时间是因为内核中存在原子加法函数 这是内核的反代码: #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable void float_atomic_add(__global float *loc, const float f){ private float old = *loc; private float sum = old +

我需要在opencl中解析稀疏矩阵向量乘法,但是我在de内核完成时的时间非常慢。我认为慢时间是因为内核中存在原子加法函数

这是内核的反代码:

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable

void float_atomic_add(__global float *loc, const float f){
private float old = *loc;
private float sum = old + f;
while(atomic_cmpxchg((__global int*)loc, *((int*)&old), *((int*)&sum)) !=              *((int*)&old)){
    old = *loc;
    sum = old + f;
}
}



 __kernel void forward(__global int* col, __global int* row, __global float* data, __global int* symmLOR_X, __global int* symm_Xpixel,__global int*    symmLOR_Y, __global int* symm_Ypixel, __global int* symmLOR_XY,__global int*           symm_XYpixel, __global int* symmLOR_Z, __global int* symm_Zpixel, __global float* x, __global float* b){

  __private int i = get_global_id(0);
  __private int p, pixel,lor, LOR_Y, LOR_X, LOR_XY;
  __private int lor_z, pixel_z;
  __private float v;



  pixel = col[i]; // j
  v = data[i];
  lor= row[i];
  //b[lor] += v * x[pixel];
  float_atomic_add(&b[lor], v * x[pixel]);


  LOR_X = symmLOR_X[lor];
  p = symm_Xpixel[pixel];
  //b[LOR_X] += v * x[p];
  float_atomic_add(&b[LOR_X], v * x[p]);

  LOR_Y = symmLOR_Y[lor];
  p = symm_Ypixel[pixel];
  //b[LOR_Y] += v * x[p];
  float_atomic_add(&b[LOR_Y], v * x[p]);

  LOR_XY = symmLOR_XY[lor];
  p = symm_XYpixel[pixel];
  //b[LOR_XY] += v * x[p];
  float_atomic_add(&b[LOR_XY], v * x[p]);

  // do Z symmetry.
  lor_z = symmLOR_Z[lor];
  pixel_z = symm_Zpixel[pixel];
  //b[lor_z] += v * x[pixel_z];
  float_atomic_add(&b[lor_z], v * x[pixel_z]);

  LOR_X = symmLOR_X[lor_z];
  p = symm_Xpixel[pixel_z];
  //b[LOR_X] += v * x[p];
  float_atomic_add(&b[LOR_X], v * x[p]);

  LOR_Y = symmLOR_Y[lor_z];
  p = symm_Ypixel[pixel_z];
  //b[LOR_Y] += v * x[p];
  float_atomic_add(&b[LOR_Y], v * x[p]);

  LOR_XY = symmLOR_XY[lor_z];
  p = symm_XYpixel[pixel_z];
  //b[LOR_XY] += v * x[p];
  float_atomic_add(&b[LOR_XY], v * x[p]);

  }

为此,我使用了一个COO格式的稀疏矩阵。

一般来说,如果你有更大的独立工作块,OpenCL工作得更好,因此如果你有一个或两个以上的矩阵要相乘,那么对每个矩阵使用一个内核,而不是将矩阵分散在多个内核上。目前,您的代码只是将矩阵乘法序列化,因此从多个内核中根本得不到什么好处。您可能还可以使用其他方法,例如仅使用一维原子加法计算矩阵的一部分,或者类似的方法,但如果可能,请对每个内核执行完整矩阵,您将看到更好的结果。感谢您的回答,现在我尝试使用不同的内核进行8次乘法,而不是一次。