为什么对thrust :: inclusive_scan的调用比后续调用要慢得多?

时间:2017-04-03 03:40:14

标签: cuda thrust

当我多次呼叫thrust::inclusive_scan时,为什么第一次比后续呼叫慢得多?

这是代码

float ttime;
for(int i=0;i<5;i++){
     cudaEvent_t start,stop; 
     cudaEventCreate(&start); 
     cudaEventCreate(&stop);
     cudaEventRecord(start,0);

     thrust::device_ptr<int > din(device_input);
     thrust::device_ptr<int > dout(device_output);
     thrust::inclusive_scan(din,din+N,dout);

     cudaEventRecord(stop,0); 
     cudaEventSynchronize(stop); 
     cudaEventElapsedTime(&ttime,start,stop);
     printf("cost %fms\n",ttime);
}

我在GTX1080上运行,结果是

cost 39.180702ms
cost 0.200704ms
cost 0.201728ms
cost 0.202752ms
cost 0.197632ms

有人可以帮忙解释一下吗?

2 个答案:

答案 0 :(得分:2)

Thrust是使用CUDA运行时API构建的,该API使用惰性context initialisation

没有记录确切的初始化序列,并且有经验证据表明它已随时间发生变化。但是,似乎上下文设置是在ad hoc basis上完成的。

慢速第一次调用可能与程序中包含推力代码的模块的加载和初始化有关。您可以通过分析代码并查看配置文件执行时间与第一次呼叫的挂钟时间来验证这一点。

答案 1 :(得分:1)

向Talonmies添加一些单词&#39;有效答案:

  • 在我的this question中,有一些鸡尾酒餐巾计算了CUDA初始化需要多长时间。

  • 我还建议,要将libthrust的加载+初始化时间与运行时API初始化开销分开,请执行以下三个阶段:

    1. 执行一些不写任何输出的虚拟内核 - 两次(T_1,T2 _)
    2. 使用(几乎)没有数据(但确实启动内核)进行libthrust调用 - 两次(T_3,T_4)
    3. 现在是真正的通话时间

粗略地说,(T_1-T_2)是CUDA负载&amp;初始时间和(T_3-T_4)是推力载荷&amp;初始时间。

  • 查看分析时间表很有帮助; CUDA将会推动#34;它的大多数初始化都是你的一个API调用 - 但不一定是第一个。