我尝试将 4800x9600 矩阵的行相加,得到一个 1x9600 矩阵。
我所做的是将 4800x9600 分成 9,600 个矩阵,每个矩阵长度为 4800。然后我对 4800 个元素执行缩减操作。
问题是,这真的很慢......
有人有什么建议吗?
基本上,我正在尝试实现 MATLAB 的 sum(...) 函数。
这是我已经验证工作正常的代码,只是速度非常慢:
void reduceRows(Matrix Dresult,Matrix DA)
{
//split DA into chunks
Matrix Dchunk;
Dchunk.h=1;Dchunk.w=DA.h;
cudaMalloc((void**)&Dchunk.data,Dchunk.h*Dchunk.w*sizeof(float));
Matrix DcolSum;
DcolSum.h=1;DcolSum.w=1;
//cudaMalloc((void**)&DcolSum.data,DcolSum.h*DcolSum.w*sizeof(float));
int i;
for(i=0;i<DA.w;i++) //loop over each column
{
//printf("%d ",i);
cudaMemcpy(Dchunk.data,&DA.data[i*DA.h],DA.h*sizeof(float),cudaMemcpyDeviceToDevice);
DcolSum.data=&Dresult.data[i];
reduceTotal(DcolSum,Dchunk);
}
cudaFree(Dchunk.data);
}
矩阵定义为:
typedef struct{
long w;
long h;
float* data;
}Matrix;
ReduceTotal() 只是调用标准 NVIDIA 缩减,对 Dchunk 中的所有元素求和,并将结果放入 DcolSum 中。
如果找不到答案,我将在 CPU 上完成所有这些操作...;(
提前非常感谢,
最佳答案
不要在每列上循环,而是在列上并行化。 4600 个线程中的每个线程对其列中的 9600 个条目求和,并将总和放在结果向量中的适当位置。
如果您正在寻找一个库来简化 Cuda 的使用,我强烈推荐 Thrust:http://code.google.com/p/thrust/
使用 Thrust,我将创建一个仿函数来将矩阵的指针保存在设备内存中,然后将其映射到一系列列索引上。仿函数的 operator() 将采用一个索引,对矩阵该列中的所有内容求和,然后返回总和。然后你将把你的总和放在一个 Thrust::device_vector 中,而不需要任何内存副本(甚至直接 CUDA 调用)。
你的仿函数可能看起来像这样:
struct ColumnSumFunctor {
const Matrix matrix;
// Make a functor to sum the matrix
ColumnSumFunctor(const Matrix& matrix);
// Compute and return the sum of the specified column
__device__
int operator()(const int& column) const;
};
关于matrix - CUDA 添加矩阵的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3312228/