C++ 我想把我的密码从CPP改成CUDA,知道吗?

C++ 我想把我的密码从CPP改成CUDA,知道吗?,c++,sorting,cuda,C++,Sorting,Cuda,我有一个无法解决的问题 问题如下 CPP代码 const int dataSize=65535; const int category=10; 浮动数据[数据大小][类别]; 常数浮动阈值=0.5f; int-cnt=0; //数据数组包含任何值 对于(int i=0;i阈值) { 数据[cnt][0]=数据[i][0]; 数据[cnt][1]=数据[i][1]; 数据[cnt][2]=数据[i][2]; 数据[cnt][3]=数据[i][3]; 数据[cnt][4]=数据[i][4]; 数据[

我有一个无法解决的问题

问题如下

CPP代码
const int dataSize=65535;
const int category=10;
浮动数据[数据大小][类别];
常数浮动阈值=0.5f;
int-cnt=0;
//数据数组包含任何值
对于(int i=0;i阈值)
{
数据[cnt][0]=数据[i][0];
数据[cnt][1]=数据[i][1];
数据[cnt][2]=数据[i][2];
数据[cnt][3]=数据[i][3];
数据[cnt][4]=数据[i][4];
数据[cnt][5]=数据[i][5];
数据[cnt][6]=数据[i][6];
数据[cnt][7]=数据[i][7];
数据[cnt][8]=数据[i][8];
数据[cnt][9]=数据[i][9];
cnt++;
}
}
通过使用这段代码,我希望“data”数组的元素收集到的值超过阈值。(没有超过阈值的元素对我来说并不重要。重要的是刚刚超过阈值。)

我想要在CUDA中运行相同结果的代码

所以我试着这样做

CUDA代码
\uuuuu全局\uuuuu无效检查阈值(浮点*数据、浮点阈值、整数*n计数)
{
int idx=threadIdx.x+blockIdx.x*blockDim.x;
如果(数据[idx*10+9]>阈值)
{
数据[nCount+0]=数据[idx*10+0];
数据[nCount+1]=数据[idx*10+1];
数据[nCount+2]=数据[idx*10+2];
数据[nCount+3]=数据[idx*10+3];
数据[nCount+4]=数据[idx*10+4];
数据[nCount+5]=数据[idx*10+5];
数据[nCount+6]=数据[idx*10+6];
数据[nCount+7]=数据[idx*10+7];
数据[nCount+8]=数据[idx*10+8];
数据[nCount+9]=数据[idx*10+9];
原子添加(nCount,1);
}
}
....
//核函数调用
checkOverThreshold>(d_数据、treshold、d_计数);
但是CUDA代码的结果并不是我所期望的

它包含大量垃圾值,甚至结果也与CPP不同

我认为nCount变量的同步问题造成了这种情况

但是,我不知道如何解决这个问题

请帮我写代码。提前感谢。

此代码已被破坏:

    data[nCount+0] = data[idx*10+0];
    data[nCount+1] = data[idx*10+1];
    data[nCount+2] = data[idx*10+2];
    data[nCount+3] = data[idx*10+3];
    data[nCount+4] = data[idx*10+4];
    data[nCount+5] = data[idx*10+5];
    data[nCount+6] = data[idx*10+6];
    data[nCount+7] = data[idx*10+7];
    data[nCount+8] = data[idx*10+8];
    data[nCount+9] = data[idx*10+9];
    atomicAdd( nCount, 1);
如果在所有这些赋值过程中修改了
nCount
,将导致无意义的结果。应该是

    int d = atomicAdd(nCount, 1);
    data[d+0] = data[idx*10+0];
    data[d+1] = data[idx*10+1];
    data[d+2] = data[idx*10+2];
    data[d+3] = data[idx*10+3];
    data[d+4] = data[idx*10+4];
    data[d+5] = data[idx*10+5];
    data[d+6] = data[idx*10+6];
    data[d+7] = data[idx*10+7];
    data[d+8] = data[idx*10+8];
    data[d+9] = data[idx*10+9];

您可以使用推力库中的流压缩功能

比如说,

#include <thrust/copy.h>
// ...
const int dataSize = 65535;
struct Datum {
  float f0, f1, f2, ..., f9;
};
Datum data[dataSize];
const float threshold = 0.5f;

struct below_threshold
{
  __host__ __device__
  bool operator()(const Datum &d)
  {
    return d.f9 <= threshold;
  }
};

// data array is contains any values
Datum *new_end = thrust::remove_if(data, data + N, below_threshold());
int cnt = new_end - data;
// first cnt elements have the f9 term > threshold
// other elements are undefined
#包括
// ...
常数int dataSize=65535;
结构基准{
浮点数f0、f1、f2、…、f9;
};
基准数据[数据大小];
常数浮动阈值=0.5f;
结构低于\u阈值
{
__主机设备__
布尔运算符()
{
返回d.f9阈值
//其他元素未定义
编辑:相关推力文件


如果你不熟悉推力,这里有一个快速的概述。它基本上是许多STL风格的容器和算法,加上一些Boost风格的钟声和口哨。真正酷的是,如果你用推力编写算法而不是定制内核,你实际上可以在CPU或GPU上运行完全相同的算法o我这里的实现草图将在CPU上运行,因为内存是在主RAM中分配的。但是,如果不使用数据的常规数组,而是使用推力::设备_向量(很像std::向量),那么推力将把数据复制到GPU,同样的推力::删除_if()与同一个函子配对的调用将产生相同的结果。我希望这能让您体验到推力,并鼓励您在其上找到更多信息。

正如SchighSchagh所建议的,推力将是一种方法。ArrayFire提供了一种更为数学化的表示方式

const int dataSize = 65535;
const int category = 10;
float data[dataSize][category];
const float threshold = 0.5f;

int cnt = 0;

// populate data

// Transfer to device
array Data(data, category, dataSize); // Column major
array idx = where(Data(9, span) > threshold);
Data = Data(span, idx);

谢谢david,我会尽力去做的。如果这方面有什么不对的地方,请告诉我。(我没有尝试编译它,因为它只是一个草图。)我还注意到您将问题标记为排序。如果您尝试进行快速排序或其他操作,您会很高兴发现推力也有内置排序。这与“流媒体压缩”我最近听说ArrayFire。看起来很酷。我会尝试使用它。
#include <thrust/copy.h>
// ...
const int dataSize = 65535;
struct Datum {
  float f0, f1, f2, ..., f9;
};
Datum data[dataSize];
const float threshold = 0.5f;

struct below_threshold
{
  __host__ __device__
  bool operator()(const Datum &d)
  {
    return d.f9 <= threshold;
  }
};

// data array is contains any values
Datum *new_end = thrust::remove_if(data, data + N, below_threshold());
int cnt = new_end - data;
// first cnt elements have the f9 term > threshold
// other elements are undefined
const int dataSize = 65535;
const int category = 10;
float data[dataSize][category];
const float threshold = 0.5f;

int cnt = 0;

// populate data

// Transfer to device
array Data(data, category, dataSize); // Column major
array idx = where(Data(9, span) > threshold);
Data = Data(span, idx);