Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 排列网格大小和块大小_C++_Cuda_Gpu - Fatal编程技术网

C++ 排列网格大小和块大小

C++ 排列网格大小和块大小,c++,cuda,gpu,C++,Cuda,Gpu,我有200个矩阵A[I](其维数为4096*48)和48个向量v[j](其维数为48*1)。我想计算A[I]*v[j],(I=0:199,j=1:47) 我在考虑如何安排昨天的网格大小和块大小。但我现在想不出答案。谁能给我一些建议吗 每个块的最大数量为512。这是我的工作环境。 下面是我的代码。它工作正常。我查过了。但它比Matlab慢:( #包括 #包括 #包括 #包括 #包括“cuda.h” 使用std::cout; 使用std::endl; 使用名称空间cv; 使用名称空间std; #包

我有200个矩阵A[I](其维数为4096*48)和48个向量v[j](其维数为48*1)。我想计算A[I]*v[j],(I=0:199,j=1:47)

我在考虑如何安排昨天的网格大小和块大小。但我现在想不出答案。谁能给我一些建议吗

每个块的最大数量为512。这是我的工作环境。

下面是我的代码。它工作正常。我查过了。但它比Matlab慢:(

#包括
#包括
#包括
#包括
#包括“cuda.h”
使用std::cout;
使用std::endl;
使用名称空间cv;
使用名称空间std;
#包括
#包括
#包括
使用名称空间std;
#定义内核大小48
////////////////////////////////////////////
类型定义结构{
整数宽度;
内部高度;
步幅;
浮动*元素;
}基质;
//矩阵乘法核的前向声明
__全局无效MatMulKernel(常数矩阵,常数矩阵,矩阵);
//矩阵乘法-主机代码
//矩阵尺寸假定为块大小的倍数
void MatMul(常数矩阵A、常数矩阵B、矩阵C)
{
//将A和B加载到设备内存
矩阵d_A;
d_A.宽度=d_A.步幅=A.宽度;d_A.高度=A.高度;
尺寸=A.宽度*A.高度*尺寸(浮动);
Cudamaloc(和d_A.元素、尺寸);
cudaMemcpy(d_A.元素,A.元素,大小,
cudamemcpyhostodevice);
矩阵d_B;
宽度=步幅=宽度;高度=高度;
尺寸=B.宽度*B.高度*sizeof(浮动);
Cudamaloc(和d_B.元素、尺寸);
cudaMemcpy(d_B.元素,B.元素,大小,
cudamemcpyhostodevice);
//在设备内存中分配C
矩阵d_C;
d_C.宽度=d_C.步幅=C.宽度;d_C.高度=C.高度;
尺寸=C.宽度*C.高度*尺寸(浮动);
Cudamaloc(和d_C.元件、尺寸);
//调用内核
dim3 dimBlock(1,B.高度);
dim3 dimGrid(A.高度,C.宽度);
MatMulKernel(d_A,d_B,d_C);
//从设备内存中读取C
cudaMemcpy(C.元件、d_C.元件、尺寸、,
cudaMemcpyDeviceToHost);
//可用设备内存
cudaFree(d_A.元素);
cudaFree(d_B.元素);
cudaFree(d_C.元素);
}
//MatMul()调用的矩阵乘法核
__全局无效MatMulKernel(矩阵A、矩阵B、矩阵C)
{
//阻止行和列
int blockCol=blockIdx.y;
int blockRow=blockIdx.x;
浮动CVValue=0;
//在Csub中执行线程行和列
int row=threadIdx.y;
int col=threadIdx.x;
//循环A和B的所有子矩阵,这些子矩阵是
//需要计算Csub
//将每对子矩阵相乘
//并累积结果
//分别用于存储Asub和Bsub的共享内存
__共享浮点数为[1][kernel_size];
__共享浮点数Bs[内核大小][1];
//将Asub和Bsub从设备内存加载到共享内存
//每个线程加载每个子矩阵的一个元素
As[0][row]=A.elements[blockRow*A.stride+row+B.height*blockCol];
Bs[row][0]=B.元素[row];
//同步以确保子矩阵已加载
//在开始计算之前
__同步线程();
//将Asub和Bsub相乘
对于(int e=0;ecout这只是一个矩阵乘法问题。如果您想让事情快速运行,就不应该编写自己的矩阵乘法代码。请使用CUBLAS Sgemm

从概念上讲,如果您将
A
矩阵按如下方式排列:

[A0]
[A1]
[A2]
...
[A199]
然后您将有一个新的矩阵
AA
,即(4096*200)行x 48列

在48x48矩阵(
VV
)中排列48个
V
向量(48x1):

(每个
V
向量是新矩阵
VV
的一列)

现在有一个矩阵乘法问题(
AA
*
VV
),即(4096*200)x48乘以48x48,得到(4096*200)x 48结果。此结果有一个长度为4096*200的列向量,其中包含您尝试执行的单个矩阵向量乘法的200个结果。每列的200个结果*48列组合起来可提供原始问题将产生的所有结果。第一列将包含
[V0]的结果
乘以200个
A
矩阵,第二列将包含
[V1]
乘以200个
A
矩阵的结果,等等

一旦您按照这种方式排列了数据,在GPU上使用CUBLAS应该是最快的方法。请注意,CUBLAS希望底层存储是列主存储,因此,如果您要重新排列数据,您可能需要记住这一点。有一种方法


在你的代码中,似乎你实际上有2000个
A
矩阵,但你的问题是指200。我在回答中使用了200作为例子,但这个概念与2000个
A
矩阵相同。

忘记你的矩阵结构,想想如何在一维数组中排列数据。一旦你这样做,gr在这种情况下,id和块大小几乎是任意的。
[A0]
[A1]
[A2]
...
[A199]
[V0][V1][V2]...[V47]