我想把我的代码从CPP改成CUDA,好吗
I want change my code from CPP to CUDA, any idea?
我有一个问题无法解决。
问题如下。
CPP代码
const int dataSize = 65535;
const int category = 10;
float data[dataSize][category];
const float threshold = 0.5f;
int cnt = 0;
// data array contains any values
for(int i=0;i<dataSize;i++)
{
if( data[i][9] > threshold )
{
data[cnt][0] = data[i][0];
data[cnt][1] = data[i][1];
data[cnt][2] = data[i][2];
data[cnt][3] = data[i][3];
data[cnt][4] = data[i][4];
data[cnt][5] = data[i][5];
data[cnt][6] = data[i][6];
data[cnt][7] = data[i][7];
data[cnt][8] = data[i][8];
data[cnt][9] = data[i][9];
cnt++;
}
}
通过使用此代码,我希望"data"数组的元素的收集值超过阈值。(没有超过阈值的元素对我来说并不重要。重要的是刚刚超过阈值。)
我想要在CUDA中运行相同结果的代码。
所以我试着这样做。
CUDA代码
__global__ void checkOverThreshold(float *data, float threshold, int *nCount)
{
int idx = threadIdx.x + blockIdx.x * blockDim.x;
if( data[idx*10+9] > threshold )
{
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);
}
}
....
// kernel function call
checkOverThreshold<<< dataSize / 128, 128 >>>(d_data, treshold, d_count);
但是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];
您可以使用Thrust库中的流压缩函数。
例如,
#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
编辑:相关推力文件链接
如果你不熟悉Thrust,这里有一个快速的概述。它基本上是很多STL风格的容器和算法,加上一些Boost风格的铃铛和口哨。真正酷的是,如果你用Thrust编写算法,而不是生成自定义内核,你实际上可以在CPU或GPU上运行完全相同的算法。因此,我这里的实现草图将在CPU上运行,因为内存分配在主RAM中。但是,如果不是使用正则数组来处理数据,而是使用thrust::device_vector(很像std::vector),那么thrust会将数据复制到GPU,并且与同一个函子配对的同一个thrust::remove_if()调用会产生相同的结果。我希望这能让你尝到Thrust的味道,我鼓励你在他们的快速入门指南上找到更多。
正如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);
相关文章:
- 编译时未启用intel oneApi CUDA支持
- 在cuda线程之间共享大量常量数据
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- CUDA内核和数学函数的显式命名空间
- 将数字打印成文字
- 用c++把小数点转换成八进制
- 模板元编程:如何将参数包组合成新的参数包
- CUDA:统一内存和指针地址的更改
- 调试 CUDA MMU 故障
- 如何在加密++中将两个源组合成新的源
- 需要将一行代码从C++ Qt翻译成PyQt
- 为什么有时我输入一个整数,程序将第一个输入的数字打印成十进制数?
- 使用 CUDA 和纹理进行图像减法
- 将 2D 推力::d evice_vector 复矩阵传递给 CUDA 内核函数
- 编译 CUDA 与数学函数的叮当
- 对 CUDA/推力中的分段数据进行成对操作
- 我想把我的代码从CPP改成CUDA,好吗
- GDB:显示函数将我的 {type} 的地址打印为整数——想改成十六进制