博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenMp多线程编程计时问题
阅读量:4286 次
发布时间:2019-05-27

本文共 3691 字,大约阅读时间需要 12 分钟。

在做矩阵乘法并行化测试的时候,在利用<time.h>的clock()计时时出现了一点问题。

首先看串行的程序:

// matrix_cpu.c#include 
#include 
#include 
#define NUM 2048void matrixMul(float *A, float *B, float *C, int M, int K, int N){    int i, j, k;    for(i = 0; i < M; i++)    {        for(j = 0; j < N; j++)        {            float sum = 0.0f;            for(k = 0; k < K; k++)            {                sum += A[i*k+k] * B[k*N+j];            }            C[i*N+j] = sum;        }    }}int main(int argc, char* argv[]){    float *A, *B, *C;    clock_t start, finish;    double duration;    A = (float *) malloc (sizeof(float) * NUM * NUM);    B = (float *) malloc (sizeof(float) * NUM * NUM);    C = (float *) malloc (sizeof(float) * NUM * NUM);    memset(A, 0, sizeof(float) * NUM * NUM);    memset(B, 0, sizeof(float) * NUM * NUM);    memset(C, 0, sizeof(float) * NUM * NUM);        printf("Start...\n");    start = clock();    matrixMul(A, B, C, NUM, NUM, NUM);    finish = clock();        duration = (double)(finish - start) / CLOCKS_PER_SEC;    printf("Time: %fs\n", duration);    return 0;}

在编译后,运行该程序,得到如下结果:

[wfshen@cu05 matrix]$ ./matrix_cpuStart...Time: 26.130000s

由于CPU是至强E5-2650,所以算得比较快(但目前仍然是串行,也就是说单核单线程),这样也要26秒了(在博主的i5-4200 ThinkPad上用时是171秒)。

加上time命令再运行一遍,结果如下:

[wfshen@cu05 matrix]$ time ./matrix_cpuStart...Time: 26.770000sreal	0m28.073suser	0m26.779ssys	0m0.019s

可以看到,时间与程序中统计的差不多,实际执行时间由于加了malloc等的时间所以长了一点,但还是合情合理的。

 

那么,再来看并行的OpenMP程序:

#include 
#include 
#include 
#define NUM 2048#define THREAD_NUM 2void matrixMul(float *A, float *B, float *C, int M, int K, int N){    int i, j, k;#pragma omp parallel for private(j,k) num_threads(THREAD_NUM)    for(i = 0; i < M; i++)    {        for(j = 0; j < N; j++)        {            float sum = 0.0f;            #pragma ivdep            for(k = 0; k < K; k++)            {                sum += A[i*k+k] * B[k*N+j];            }            C[i*N+j] = sum;        }    }}int main(int argc, char* argv[]){    float *A, *B, *C;    clock_t start, finish;    double duration;    A = (float *) malloc (sizeof(float) * NUM * NUM);    B = (float *) malloc (sizeof(float) * NUM * NUM);    C = (float *) malloc (sizeof(float) * NUM * NUM);    memset(A, 0, sizeof(float) * NUM * NUM);    memset(B, 0, sizeof(float) * NUM * NUM);    memset(C, 0, sizeof(float) * NUM * NUM);    printf("Start...\n");    start = clock();    matrixMul(A, B, C, NUM, NUM, NUM);    finish = clock();    duration = (double)(finish - start) / CLOCKS_PER_SEC;    printf("Time: %fs\n", duration);    return 0;}

可以看到,该OpenMP程序只使用了两个线程,那么运行时间理论上来说能减半。

在编译后,运行该程序,得到如下结果:

[wfshen@cu05 matrix]$ ./matrix_ompStart...Time: 26.550000s

这就奇怪了,明明心里面数了一下大概花了15秒,但是为什么计时还是26秒呢?

再加上time命令运行一遍:

[wfshen@cu05 matrix]$ time ./matrix_ompStart...Time: 26.440000sreal	0m13.438suser	0m26.457ssys	0m0.016s

可以看到,实际的运行时间是13秒,但是user却超过了13秒,且几乎是real的两倍。

查了一下,发现了这样的解释:

real: 墙上时间,即程序从开启到结束的实际运行时间user: 执行用户代码所花的实际时间(不包括内核调用),指进程执行所消耗的实际CPU时间sys:该程序在内核调用上花的时间

 在,单线程串行的时候,只有一个线程在运行,那么user所代表的就是一个cpu的时间。然而,当到多线程的情况下,一个进程可能有多个线程并行执行,但是user把所有的线程时间都加起来了,也就是算了一个总时间,这样,user的时间也就基本上等于单线程时的user时间。

这样,我们把线程数调到4,再运行代码(大概7秒):

[wfshen@cu05 matrix]$ ./matrix_ompStart...Time: 27.270000s[wfshen@cu05 matrix]$ time ./matrix_ompStart...Time: 27.170000sreal	0m7.486suser	0m27.176ssys	0m0.018s

可以发现,实际运行时间7秒,CPU总时间27秒,差不多:

再把线程数调到16,再运行代码(大概2秒多):

[wfshen@cu05 matrix]$ ./matrix_ompStart...Time: 33.980000s[wfshen@cu05 matrix]$ time ./matrix_ompStart...Time: 33.530000sreal	0m2.241suser	0m33.479ssys	0m0.075s

可以发现,CPU总时间有增加的趋势,不过实际时间还是大有减少。E5-2650是8核心16线程,再往上加线程时间反而会增长。

 

总结:在多线程的情况下,还是用time命令看时间吧。

注:转载仅作为笔记使用,如有侵权,请联系。

亲测,使用clock()并行计时时,随着合数增加,运行时间增加。建议使用gettimeofday().

你可能感兴趣的文章
【找回Win8系统不见的附件目录&小工具】
查看>>
【教你几种禁止修改IP的方法】
查看>>
思量QQ本地会员v3.8官方2013版【免费使用部分QQ会员功能】
查看>>
【U盘修复工具的使用教程】
查看>>
【问答解题:xp无法连接wpa加密怎么办?】
查看>>
【Win7系统 沙滩啤酒桌面主题】
查看>>
【.NET支持上下左右移动操作】
查看>>
【用Win7备份与还原让系统轻松回魂】
查看>>
【用Win7自带的DVD Maker制作视频】
查看>>
【幸福相守Windows7桌面热门主题】
查看>>
【天天酷跑新手全攻略】
查看>>
【有道云笔记手机PC端自动同步】
查看>>
【黑色蕾丝性感女神XP电脑主题】
查看>>
【XP系统命令提示符都有哪些运用技巧】
查看>>
【4个Win7系统轻松清理记录小技巧】
查看>>
【页面脚本错误快速解决方案】
查看>>
【php输出内容乱码解决方法】
查看>>
【Win8两种安全模式互相切换图形说明】
查看>>
【Win7系统去掉磁盘保护教程】
查看>>
【炫酷战机Win7热门主题】
查看>>