for(int i=0;i<col;i++)
{
for(int j=0;j<row;j++)
{
matrix[i+j*col];
}
}
如果我先把文件中的数据转置,是不是读取效率就高了呢?第 i 列的数据就变成转置后第i 行的数据,
for(int j=0;j<row;j++)
{
for(int i=0;i<col;i++)
{
matrix[i+j*col];
}
}
是不是后面这种访问效率更高呢?
for(int i=0;i<col;i++)
{
for(int j=0;j<row;j++)
{
matrix[i+j*col];
}
}
如果我先把文件中的数据转置,是不是读取效率就高了呢?第 i 列的数据就变成转置后第i 行的数据,
for(int j=0;j<row;j++)
{
for(int i=0;i<col;i++)
{
matrix[i+j*col];
}
}
是不是后面这种访问效率更高呢?
不好意思,前面几句话没有显示:“我想读取文件中的矩阵的一列,如下所示:”
这个问题真的不好回答,你更改后的效率应该要高一些,因为缓存利用更好了。本质上来说,合并访问和cpu的缓存都是局部性的利用,但是利用的方式不同。
嗯,我试试看吧,程序里有好多这种情况,就是多了步矩阵转置~
合并访问是CUDA里面的一个概念,是用来衡量访存效率的。我认为这个概念和C语言不直接相关,因为CUDA C也是C的扩展,和一般的C一样数组都是按行存放的。但是在CPU实现上,需要单个核心/线程在循环里面连续读取的数据是连续的,这样cache命中率高,被丢弃的数据少。而在CUDA中,要求一个warp里面相邻线程的同一次读取的数据在一段连续的对齐的存储空间内,这样cache命中率高,被丢弃的数据少。
所以,我认为这种访存效率的问题,实际上是和硬件结构的关系更大一些,而和语言的关系较小。
关于您两段代码的比较,请参考3#风辰大的意见。
以及,除非你能统一数据格式,都用约定好的形式(转置形式或者不转置的形式),否则如果在整个程序里面转来转去的话,转置自身也是费时的。
祝您编码愉快~
好的,我现在的这个程序出现了新的问题,在样本是600121和样本是5000961的时候,结果是正确的,但是在样本为600*7381的时候,我的程序提示错误了,出错的代码是
void matMulmat(double *A,double *B,double *C,int M,int N,int K,const double alpha,const double beta) //矩阵相乘的CUBLAS库中的cublasDgemm()函数调用
{
int lda=N;
int ldb=K;
int ldc=N;
int m=N;
int n=M;
int k=K;
cublasOperation_t transa,transb;
transa=CUBLAS_OP_N;
transb=CUBLAS_OP_N;
size_t size_A=M*K*sizeof(double);
size_t size_B=K*N*sizeof(double);
size_t size_C=M*N*sizeof(double);
cublasStatus_t stat;
cudaError cudaStat;
cublasHandle_t handle;
stat=cublasCreate(&handle);
if(stat!=CUBLAS_STATUS_SUCCESS)
{
printf("CUBLAS initialization failed\n");
}
double *dev_A,*dev_B,*dev_C;
cudaStat=cudaMalloc((void**)&dev_A,size_B);
if(cudaStat!=cudaSuccess)
{
printf("Matrix A on device memory allocation failure!\n");
}
cudaStat=cudaMalloc((void**)&dev_B,size_A);
if(cudaStat!=cudaSuccess)
{
printf("Matrix B on device memory allocation failure!\n");
}
cudaStat=cudaMalloc((void**)&dev_C,size_C);
if(cudaStat!=cudaSuccess)
{
printf("Matrix C on device memory allocation failure!\n");
}
cudaStat=cudaMemcpy(dev_A,B,size_B,cudaMemcpyHostToDevice);
if(cudaStat!=cudaSuccess)
{
printf("Matrix from host(A) to device(dev_A) copy failure!\n");
}
cudaStat=cudaMemcpy(dev_B,A,size_A,cudaMemcpyHostToDevice);
if(cudaStat!=cudaSuccess)
{
printf("Matrix from host(B) to device(dev_B) copy failure!\n");
}
cublasDgemm(handle,transa,transb,m,n,k,&alpha,dev_A,lda,dev_B,ldb,&beta,dev_C,ldc);
if(stat!=CUBLAS_STATUS_SUCCESS)
{
printf("Function cublasDgemm() excute failure!\n");
cudaFree(dev_A);
cudaFree(dev_B);
cudaFree(dev_C);
cublasDestroy(handle);
}
cudaStat=cudaMemcpy(C,dev_C,size_C,cudaMemcpyDeviceToHost);
if(cudaStat!=cudaSuccess)
{
printf("Matrix from device(dev_C) to host(C) copy failure!\n");
}
cudaFree(dev_A);
cudaFree(dev_B);
cudaFree(dev_C);
cublasDestroy(handle);
}
[
也不是一运行就出错,而是运行了好几个循环之后,提示这个错误[attach]2880[/attach]
是不是这个矩阵相乘的函数调用次数太多了,造成CUBLAS的反复初始化,数据反复传输啊,这个函数可能会被调用上万次。后来我弃用cublas,转而用CULA库,其实还是cublas,只不过是调用形式有些区别,结果也出错误了。
未能目测出有什么问题,一般来说反复调用应该没事。
建议仔细检查下有没有越界,或者代码其他地方有没有什么问题。
你运行的同时使用nvidia-smi看一下显存占用,我怀疑是因为最后没有显存可分配了.