Matrix 非方矩阵CUDA的通用快速转置
SDK提供了一个处理方矩阵转置的示例和策略,但是有没有一种在非方矩阵上执行转置的好方法?我目前有一个非常幼稚的实现,如下所示,这可能很糟糕:Matrix 非方矩阵CUDA的通用快速转置,matrix,cuda,transpose,Matrix,Cuda,Transpose,SDK提供了一个处理方矩阵转置的示例和策略,但是有没有一种在非方矩阵上执行转置的好方法?我目前有一个非常幼稚的实现,如下所示,这可能很糟糕: template<class S> __global__ void transpose(S *Source, S *Destination, int SizeX, int SizeY) { int tid = threadIdx.x + blockIdx.x * blockDim.x; if (tid<SizeX*Siz
template<class S>
__global__ void transpose(S *Source, S *Destination, int SizeX, int SizeY) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid<SizeX*SizeY) {
int X = tid % SizeX;
int Y = tid / SizeX;
//(x,y) => (y,x)
int newId = (SizeY*X) + Y;
Destination[newId] = Source[tid];
}
}
模板
__全局无效转置(S*源、S*目的地、int SizeX、int SizeY){
int tid=threadIdx.x+blockIdx.x*blockDim.x;
若有(tid)(y,x)
int newId=(SizeY*X)+Y;
目的地[newId]=来源[tid];
}
}
在这里,我的想法是只使用必要的线程/块转置矩阵的方形部分(每个线程交换方形子矩阵的两个条目),然后遍历并转置其余条目
__global__ void kernelTranspuesta(float *a, float *c, int m, int n) {
int i = threadIdx.x + blockIdx.x*blockDim.x;
int j = threadIdx.y + blockIdx.y*blockDim.y;
int smallest = M < N ? M : N;
while( j < smallest ){
i = threadIdx.x + blockIdx.x*blockDim.x;
while( i < j ){
c[i*m+j] = a[j*n+i];
c[j*m+i] = a[i*n+j];
i+= blockDim.x*gridDim.x;
}
if(i == j)
c[j*m+i] = a[i*n+j];
j+= blockDim.y*gridDim.y;
}
if( M > N ) {
i = threadIdx.x + blockIdx.x*blockDim.x + N;
j = threadIdx.y + blockIdx.y*blockDim.y;
while( i < M ){
j = threadIdx.y + blockIdx.y*blockDim.y;
while( j < N){
c[j*m+i] = a[i*n+j];
j+= blockDim.y*gridDim.y;
}
i+= blockDim.x*gridDim.x;
}
}else{
i = threadIdx.x + blockIdx.x*blockDim.x;
j = threadIdx.y + blockIdx.y*blockDim.y + M;
while( i < M ){
j = threadIdx.y + blockIdx.y*blockDim.y + M;
while( j < N){
c[j*m+i] = a[i*n+j];
j+= blockDim.y*gridDim.y;
}
i+= blockDim.x*gridDim.x;
}
}
}
\uuuu全局\uuuuu无效内核传输(浮点*a,浮点*c,整数m,整数n){
int i=threadIdx.x+blockIdx.x*blockDim.x;
int j=线程IDX.y+块IDX.y*块DIM.y;
int最小值=MN){
i=线程IDX.x+块IDX.x*blockDim.x+N;
j=螺纹内径x.y+块内径x.y*blockDim.y;
而(我
内核调用是
dim3 hilos(16,16); // hilos(blockDim.x, blockDim.y)
dim3 bloques(8,8); // bloques(gridDim.x, gridDim.y)
kernelTranspuesta<<<bloques, hilos>>>(aD, cD, m, n);
dim3hilos(16,16);//hilos(blockDim.x,blockDim.y)
dim3 bloques(8,8);//bloques(gridDim.x,gridDim.y)
核运输(aD,cD,m,n);
我在512x256和256x512矩阵上进行了测试,请告诉我您的想法。为什么“可能很糟糕”-你对内核进行了基准测试吗?它达到了峰值内存带宽的多少?可能很糟糕,因为我以前没有测试过它。探查器报告了27GB/s的写入吞吐量和5.3GB/s的读取。可能最好是将块读入共享内存,进行转置并写入块。你在这里的写入根本没有合并。没有如果你有非正方形的任意大小的行/列,这似乎不是确定块大小的可靠方法?看起来不错,我通常在3000x2000左右的矩阵上。在共享内存空间中进行转置不是更快吗?