0

我正在研究AxBCUDA 中的特殊矩阵-矩阵乘法 ( ),其中A是随机MxM矩阵,BMxN矩阵。在下面的代码中,M只是2000但在实际情况下,它将被替换为大数字,因此给出的不仅仅是2GB矩阵A。实际上, 的所有元素A都是随机的,并且限制在某个范围内,因此将由 randomize 函数生成。

我已经编写了下面的代码,其中的每个元素A都是从数组中随机选取的,因此原始元素AxB将被修改为长度M乘以的向量B。这是我编写代码的方式,但它似乎不起作用

#include <iostream>
#include <cusp/complex.h>

using namespace std;

#define M 2000
#define N 300

typedef cusp::complex<double> Complex;

__global__ void MVult(Complex* ad, Complex* bd, Complex* cd, int m1, int n1, int n2) 
{
  int x = (blockIdx.x * blockDim.x) + threadIdx.x;
  int y = (blockIdx.y * blockDim.y) + threadIdx.y;

  if(x < n2 && y < m1) 
  {   
    Complex sum = Complex(0.0, 0.0);
    int ridx = (rand()%(M-1)); // here I randomize the starting ridx 
    for(int i=0; i<n1; i++) sum += ad[ridx + i] * bd[i * n2 + x];
    cd[y * n2 + x] = v;
  }
}

int main(int argc, char *argv[])
{
  std::vector< Complex > _A(2*M+1);
  std::vector< Complex > _B(M*N);
  Complex *A, *B, *C;

  cudaMalloc((void**)&A, (2*M+1)*sizeof(Complex));
  cudaMalloc((void**)&B, M*N*sizeof(Complex));
  cudaMalloc((void**)&C, M*N*sizeof(Complex));

  for (int i=0; i<2*M+1; i++) _A[i] = Complex((double)i, (double)i);
  for (int i=0; i<M*N; i++) _B[i] = Complex(1.0, 0.0);

  cudaMemcpy( A, &_A[0], (2*M+1)*sizeof(Complex), cudaMemcpyHostToDevice );
  cudaMemcpy( B, &_B[0], (M*N)*sizeof(Complex), cudaMemcpyHostToDevice );

  dim3 block(32, 32);           
  dim3 grid((N+31)/32, (M+31)/32);

  MVult<<<grid, block>>>(A, B, C, M, M, N);
  cudaMemcpy(&_B[0], &C[0], (M*N)*sizeof(Complex), cudaMemcpyDeviceToHost);

  cudaFree(A);
  cudaFree(B);
  cudaFree(C);

  return 0;
}

我尝试使用 CPU 循环来循环它M,每次运行向量和矩阵乘法(在 CUDA 中完成),但它太慢了。我正在寻找一种更快的方法来解决问题。

4

1 回答 1

1

您的代码会很慢,主要有两个原因:

  1. 在构建矩阵的方式中A,您正在随机访问全局内存,因此防止合并访问;
  2. 正如@talonmies 在下面的评论中指出的那样,您正在实现自己的矩阵向量乘法例程,这肯定会比高度优化的例程慢cuBLAS

为了加快你的代码,而不是使用你的__global__功能MVult,你可以/应该使用

  1. cuRANDA用随机数填充矩阵;
  2. cuBLAS执行A和之间的矩阵乘法B,特别是cublasCgemm()对于单精度复杂计算。

如果矩阵A太大,那么您可以尝试将计算划分A*B为更小的块,然后使用cuBLAS(using cublasSetStream()) 的批处理功能尝试使用 CUDA 流实现并发执行。

您可能还希望使用也推力查看以下示例:

使用 CUDA 和 CUBLAS、CURAND 和 Thrust 在 GPU 上进行矩阵乘法

正如@talonmies 所建议的那样,您可能还希望重新考虑您的方法。例如,如果A是一个随机矩阵,那么A*B也将是随机的。是否有可能利用随机方法直接构造矩阵的统计数据A和可能的先验知识,而无需使用矩阵乘法?BA*B

于 2013-09-11T21:00:25.807 回答