–ptxas-options=-v里面很多参数看不懂,跪求高人解释。
同样看不懂。跪求高人解释。
#include <stdio.h>
#include <cuda_runtime.h>
#include <assert.h>
#define N 4
void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err)
{
fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
exit(EXIT_FAILURE);
}
}
__constant__ float c_a=1.3;
__global__ void hey(float *d_a1)
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
__shared__ float s_a[N];
// float r_a=1.1(此句加与不加都显示用了6个register)
s_a[tid]=1.0;
d_a1[tid] = d_a1[tid] + s_a[tid] + c_a;
}
int main()
{
int i;
float h_a[N];
float *d_a;
size_t msize=N*sizeof(float);
for (i=0; i<N; i++){
h_a[i]=i*2.0;
}
cudaMalloc((void**)&d_a, msize);
cudaMemcpy(d_a, h_a, msize, cudaMemcpyHostToDevice);
dim3 dimBlock( 1 );
dim3 dimThread( N );
hey <<< dimBlock, dimThread >>> (d_a);
checkCUDAError("kernel invocation");
cudaMemcpy (h_a, d_a, msize, cudaMemcpyDeviceToHost);
printf("h_a=%f,%f,%f,%f\n", h_a[0],h_a[1],h_a[2],h_a[3]);
cudaFree(d_a);
return 0;
}
编译时加–ptxas-options=-v,可得以下信息
ptxas info : 0 bytes gmem, 4 bytes cmem[2]
ptxas info : Compiling entry function ‘_Z3heyPf’ for ‘sm_20’
ptxas info : Function properties for _Z3heyPf
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 6 registers, 16 bytes smem, 40 bytes cmem[0]
可以看懂的是 4 bytes cmem[2]对应程序里面的__constant__ float c_a,以及16 bytes smem对应程序里面的__shared__ float s_a[4]
问题:(1)6个registers如何算得?
(2)40 bytes cmem[0]是什么?
(3)如程序中所示,如果在global函数中(22行)定义并赋初值float r_a=1.1,再次按–ptxas-options=-v编译,显示的也是used 6 registers,而且其他各种内存使用都不变,为何?是r_a未定义在register上吗?
楼主您好,无公开资料。无法评价ptxas。抱歉。
您可以等待NVIDIA原厂支持为您提供资料以及详细信息。
我用nvidia visual profiler拿来实验,在global函数中多定义一个float(就是上面代码的22行),结果显示register并没有增加,不知为何
因为ptxas的相关资料不能被公开,所以您问的cmem[n]的问题无法直接回答。
您可以让NVIDIA原厂支持回答。
关于寄存器不增加,这个很正常,当且仅当:
(1)1个常量不能作为立即数
(2)1个常量不能放入constant cache
(3)1个常量只能放入寄存器
(4)当前已经分配的寄存器数目中,没有空闲的。
才可能会增加寄存器数量。
感谢来访。
嗯,又有了更多的理解,十分感谢!
服务您是我的荣幸。
期待您的再次来访。
那这就产生一个问题:我们在编程时无法准确估计寄存器占用的数量?
楼主您好,您在编码的时候无法直接得到这个。
但您编译的时候会得到used xxxx registers的信息的。
感谢来访。
那也只能这样了,但是寄存器的数量对代码的编写和算法产生限制,无法在编码的时候准确估计寄存器使用的话,是件挺麻烦的事情。
我建议您专心写代码即可,编译器的安排是编译器的事。
操心这个时间,不如多泡泡妞了,您觉得呢?
道理是没错,不过我是泡妞之余搞这玩意儿的
好吧。如果你真的需要一边写代码一些能计算出寄存器的使用,
你需要:
(1)统计每个变量的分配位置(例如是否真的需要在寄存器中,还是作为立即数还是作为常数等)
(2)统计到目前未知已经分配的寄存器数目,统计前面的那些寄存器变量是否已经超过有效生存期,是否可以被标记为空闲了,从而决定你是否需要分配一个新的寄存器。
(3)评估为了性能的影响,一个长期不用的寄存器是将它的值交换出去呢?让出新空间给新变量用呢?还是让它长期留着,节省交换代价,直接分配一个新寄存器。
(4)需要知道硬件的分配粒度,例如某些卡如果你知道分配13个和分配16个寄存器实际运行资源占用无区别,你可以大胆的多分配3个。还是不能。
(5)…
(6)…
正因为这些以及还有更多更多的原因,你大脑进行编译、以及后续的寄存器分配非常非常折腾。我还是建议您编译下看看编译器给出的结果。
真抱歉,我之前没有继续追问的意思,,,不过感谢你详细的回复,又可以让我学习学习。