解释CUDA探查器日志文件

解释CUDA探查器日志文件,cuda,profiler,thrust,nvcc,Cuda,Profiler,Thrust,Nvcc,下面是在一些代码上运行CUDA profiler(nvprof)的日志文件,这些代码混合了推力、cublas和curand。第一个是我写的内核,所以没有问题。但我不知道如何解释第2行到第5行,这占用了大量的运行时间 > Time(%) Time Calls Avg Min Max Name % s ms ms ms > > 28.12 6.82 24,543.00 0.2

下面是在一些代码上运行CUDA profiler(nvprof)的日志文件,这些代码混合了推力、cublas和curand。第一个是我写的内核,所以没有问题。但我不知道如何解释第2行到第5行,这占用了大量的运行时间

>  Time(%)   Time    Calls   Avg     Min     Max    Name  %      s       ms      ms      ms
>   
>  28.12     6.82    24,543.00   0.28    0.01    0.64   dev_update_dW1(doub....)
>  23.78     5.77    12,272.00   0.47    0.46    0.49   void thrust::system::cud....
>  14.32     3.47    12,272.00   0.28    0.28    0.29   void thrust::system::cud....
>  10.82     2.62    12,272.00   0.21    0.21    0.22   void thrust::system::cud....
>  4.93      1.20    24,544.00   0.05    0.05    0.05   void thrust::system::cud....
>  3.98      0.96    12,272.00   0.08    0.08    0.09   Act_dAct(double*, long, double*, double*)
第2至第5行全文如下:

第二行:无效推力::系统::cuda::细节::细节::启动\关闭\按\值>,推力::计数\迭代器,推力::空\类型,推力::空\类型,推力::空\类型,推力::空\类型,推力::空\类型,推力::空\类型>>,推力::空\类型int64,推力::元组,推力::细节::正常\迭代器,推力::系统::cuda::细节::标记,推力::使用默认值,推力::使用默认值>>,推力::系统::细节::通用::细节::最大元素减少>,推力::系统::cuda::细节::细节::阻塞线程\数组>>(双精度)

第三行:无效推力::系统::cuda::细节::细节::启动\u闭包\u按\u值>,推力::细节::正常\u迭代器>,推力::空\u类型,推力::空\u类型,推力::空\u类型,推力::空\u类型,推力::空\u类型,推力::空\u类型>>,无符号int,推力::细节::设备一元变换\u函子,推力::系统::cuda::细节::细节::阻塞线程\u数组>>(双精度)

第四行:无效推力::系统::cuda::细节::细节::按值启动关闭,双精度,推力::使用默认值>,双精度,推力::细节::正常迭代器>,推力::加号,推力::系统::cuda::细节::阻塞的线程数组>(exp\u functor)

第五行:无效推力::系统::cuda::细节::细节::按值启动\u闭包\u,无符号整数,推力::细节::设备\u生成\u函子>,推力::系统::cuda::细节::细节::阻塞的线程\u数组>>(双精度)

编辑:

我有一个函数(softmax),它使用max\u元素和transform\u reduce

void Softmax_ThrustMatrix(thrust::device_vector<double>& mat, int Nrow, int Ncol, thrust::device_vector<double>& Outmat) {
thrust::device_vector<double> x(Ncol, 0.0);
thrust::device_vector<double> v(Ncol, 0.0);
thrust::device_vector<double>::iterator mx;
double tmp = 0.0, logsm=0.0;
dim3 grid, block;

block.x = 16;
block.y = 1;
grid.x = Ncol / block.x + 1;
grid.y = 1;

for ( int i=0; i < Nrow; i++ ) {
    GetRow<<<grid,block>>>(thrust::raw_pointer_cast(&mat[0]), i, Nrow, Ncol, thrust::raw_pointer_cast(&x[0]));

    mx = thrust::max_element(x.begin(), x.end());

    tmp = thrust::transform_reduce(x.begin(), x.end(), exp_functor(*mx), 0.0, thrust::plus<double>() );
    logsm = *mx + log(tmp);

    thrust::transform(x.begin(), x.end(), v.begin(), exp_functor(logsm));

    SetRow<<<grid,block>>>(thrust::raw_pointer_cast(&v[0]), i, Nrow, Ncol, thrust::raw_pointer_cast(&Outmat[0]));
    }
}
void Softmax\u推力矩阵(推力::装置矢量和mat、int Nrow、int Ncol、推力::装置矢量和Outmat){
推力:器件_矢量x(Ncol,0.0);
推力:装置矢量v(Ncol,0.0);
推力::设备向量::迭代器mx;
双tmp=0.0,logsm=0.0;
dim3网格,块;
块x=16;
块y=1;
grid.x=Ncol/block.x+1;
网格y=1;
对于(int i=0;i
低级别的推力代码与CUDA代码没有任何区别(至少针对GPU的推力代码)。作为一个模板库,推力在源代码级别抽象了CUDA的许多方面,但是探查器不知道推力代码和普通CUDA代码之间有什么区别

第2-5行表示4次内核启动时的探查器数据。从它们的语法可以明显看出,它们可能不是您编写的内核——它们来自于推力模板函数的深处

“启动关闭”是在引擎盖下的推力,表示由推力启动的内核执行某些功能。由于您在显示的代码中有3个推力调用,并且还显示了您编写的
GetRow
SetRow
内核,并且这些内核没有显示在您的分析器输出的任何地方,因此我不清楚您显示的分析器输出是否与您显示的代码相关。您还没有显示调用确实出现在输出中的内核的代码(
dev\u update\u dW1
Act\u dAct
),因此我很清楚,您显示的代码对于进一步解释探查器输出是没有用的

在任何情况下,第2-5行代表由推力启动的CUDA内核,这些内核来自代码中的推力调用(某处)

请注意,推力也可以为其他一些不明显的目的启动内核,例如设备向量的实例化