请问C语言有没有类似合并访问的问题



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看一下显存占用,我怀疑是因为最后没有显存可分配了.