nvcc编译器未优化
为什么编译器没有做一些可以在内核中完成的琐碎优化?我有以下矩阵乘法代码:nvcc编译器未优化,c,optimization,compiler-construction,nvcc,C,Optimization,Compiler Construction,Nvcc,为什么编译器没有做一些可以在内核中完成的琐碎优化?我有以下矩阵乘法代码: __global__ void matrixMultiply(float * A, float * B, float * C, int numARows, int numAColumns, int numBRows, int numBColumns, int numCRows, int numCColumns) { int n=numAColumns; in
__global__ void matrixMultiply(float * A, float * B, float * C,
int numARows, int numAColumns,
int numBRows, int numBColumns,
int numCRows, int numCColumns) {
int n=numAColumns;
int Row=blockIdx.x*blockDim.x+threadIdx.x;
int Col=blockIdx.y*blockDim.y+threadIdx.y;
if((Row<numCRows) && (Col<numCColumns)){
for(int k=0;k<n;++k){
C[Row*numCColumns+Col]+=
A[Row*numAColumns+k]*B[k*numBColumns+Col];
}
}
}
在最后一种情况下,
C
的全局内存只被访问一次,而在第一种情况下,它在循环中被多次访问。这种优化通常不是由编译器完成的吗?在我的测试中,这两个代码的性能相差约30%,我正在做nvcc-O3…因为C
没有声明为\uuuuuuuuuuuuuu
编译器无法知道C
是否与a
或B
是同一个矩阵,因此无法执行上述优化。当我改为使用float*\uuuuuuuuuuuuu restrict\uuuuc
时,两者的时间几乎相同。谢谢Chris Dodd。代码不一样。我想你想要的是C[Row*numcolumns+Col]+=
而不是C[Row*numcolumns+Col]=
。对不起,是的。。。我更正了它。因为在计算过程中,不同的线程可以访问C,所以代码就不一样了。而且在第一个示例中,您也没有将C归零。@Dave:因为没有障碍,所以其他线程可能会做什么是不相关的。真正的问题是C
可能与A
或B
重叠(或是相同的矩阵),这使得这两个例程非常不同<代码>\uuuu限制\uuuu完全是另外一回事。或者,更确切地说,它可能是另一种东西。总的来说,使用标准名称比使用非标准的、可能特定于编译器的扩展名要好。
__global__ void matrixMultiply(float * A, float * B, float * C,
int numARows, int numAColumns,
int numBRows, int numBColumns,
int numCRows, int numCColumns) {
int n=numAColumns;
int Row=blockIdx.x*blockDim.x+threadIdx.x;
int Col=blockIdx.y*blockDim.y+threadIdx.y;
if((Row<numCRows) && (Col<numCColumns)){
float Cvalue=0;
for(int k=0;k<n;++k){
Cvalue+=A[Row*numAColumns+k]*B[k*numBColumns+Col];
}
C[Row*numCColumns+Col]=Cvalue;
}
}