码迷,mamicode.com
首页 > 其他好文 > 详细

0_Simple__clock

时间:2017-10-27 01:17:36      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:reads   edr   emc   结果   sizeof   分享   nbsp   提升   red   

使用 clock() 函数在CUDA核函数内部进行计时。

源代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 #include "cuda_runtime.h"
 5 #include "device_launch_parameters.h"
 6 #include <helper_cuda.h>
 7 #include <helper_functions.h>
 8 
 9 __global__ static void timedReduction(const float *input, float *output, clock_t *timer)
10 {
11     extern __shared__ float shared[];// 共享内存数组大小为 blockDim.x 的2倍
12 
13     const int tid = threadIdx.x;
14     const int bid = blockIdx.x;
15 
16     if (tid == 0) timer[bid] = clock();// 零号线程负责计时,所有线程块都做一模一样的规约工作
17 
18     shared[tid] = input[tid];
19     shared[tid + blockDim.x] = input[tid + blockDim.x];
20 
21     // 二分规约求最小值
22     for (int d = blockDim.x; d > 0; d /= 2)
23     {
24         __syncthreads();
25 
26         if (tid < d)
27         {
28             float f0 = shared[tid];
29             float f1 = shared[tid + d];
30             if (f1 < f0)
31                 shared[tid] = f1;
32         }
33     }
34 
35     if (tid == 0) output[bid] = shared[0];
36     __syncthreads();
37 
38     if (tid == 0) timer[bid + gridDim.x] = clock();
39 }
40 
41 #define NUM_BLOCKS    1
42 #define NUM_THREADS   1024
43 
44 int main(int argc, char **argv)
45 {
46     printf("CUDA Clock sample\n");
47 
48     int dev = findCudaDevice(argc, (const char **)argv);
49 
50     float *dinput = NULL;
51     float *doutput = NULL;
52     clock_t *dtimer = NULL;
53 
54     clock_t timer[NUM_BLOCKS * 2];
55     float input[NUM_THREADS * 2];
56 
57     for (int i = 0; i < NUM_THREADS * 2; i++)
58         input[i] = (float)i;
59 
60     cudaMalloc((void **)&dinput, sizeof(float) * NUM_THREADS * 2);
61     cudaMalloc((void **)&doutput, sizeof(float) * NUM_BLOCKS);
62     cudaMalloc((void **)&dtimer, sizeof(clock_t) * NUM_BLOCKS * 2);
63 
64     cudaMemcpy(dinput, input, sizeof(float) * NUM_THREADS * 2, cudaMemcpyHostToDevice);
65 
66     timedReduction << <NUM_BLOCKS, NUM_THREADS, sizeof(float) * 2 * NUM_THREADS >> >(dinput, doutput, dtimer);
67 
68     cudaMemcpy(timer, dtimer, sizeof(clock_t) * NUM_BLOCKS * 2, cudaMemcpyDeviceToHost);
69 
70     cudaFree(dinput);
71     cudaFree(doutput);
72     cudaFree(dtimer);
73 
74     long double avgElapsedClocks = 0;
75 
76     for (int i = 0; i < NUM_BLOCKS; i++)
77         avgElapsedClocks += (long double)(timer[i + NUM_BLOCKS] - timer[i]);
78 
79     avgElapsedClocks = avgElapsedClocks / NUM_BLOCKS;
80     printf("Average clocks/block = %Lf\n", avgElapsedClocks);
81 
82     getchar();
83     return EXIT_SUCCESS;
84 }

 

? 输出结果。一共有 NUM_BLOCKS 个线程块,每个线程块利用 NUM_THREADS 个线程查找其两倍长度向量中的最小值,给出平均计算时间:

CUDA Clock sample
GPU Device 0: "GeForce GTX 1070" with compute capability 6.1

Average clocks/block = 44046.328125

比较不同的 blockDim.x 和 threadDim.x 情况结果如下图表所示。

 技术分享

技术分享

 

? 涨姿势:
● 在核函数中也能使用 <time.h>中的 clock_t 变量、clock() 函数等进行计时。

 

● 当使用的 block 数量少于一定的阈值时,计算效率处于较低水平。随着使用的 block 数量的上升,计算效率现有较大提升、后保持不变。

 

0_Simple__clock

标签:reads   edr   emc   结果   sizeof   分享   nbsp   提升   red   

原文地址:http://www.cnblogs.com/cuancuancuanhao/p/7739608.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!