pthread,统计执行时间的问题

NewToeee 2012-12-11 12:05:28

/*启动线程并行计算行列式*/
void compute_det()
{
int* thread_id = new int[thread_num];
for(int i=0;i<thread_num;i++)
thread_id[i] = i;
for(int i=0;i<thread_num;i++){
int* t = thread_id+i;
pthread_create(&threads[i],NULL,cacu_thread,(void*)t);
}
for(int i=0;i<thread_num;i++)
pthread_join(threads[i],NULL);
}



/*主函数中调用计算行列式的值*/
det_value = 0.0;
clock_t stime,etime;
stime = clock();
cout<<stime<<endl;
compute_det();
for(int i=0;i<thread_num;i++)
det_value += private_det_value[i];
etime = clock();
cout<<etime<<endl;
cout<<"The determinant's value is "<<det_value<<"."<<endl;
double time_used = ((double)(etime - stime)) / CLOCKS_PER_SEC;


程序可以执行。在计算10阶行列式时,启动1个线程大约用时3秒(大致和人为数的差不多)。
但是在用10个线程并行计算时,统计结果却是8秒多,而我心数明显地感觉只有1秒不到的时间。
也就是说,时间统计出了错。路过大虾们,错在何处?怎么改?谢谢啦!
...全文
612 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewToeee 2012-12-11
  • 打赏
  • 举报
回复
我笑点有点低啊。 不过确实是这样,实际影响程序执行的因素很多,要准确地测出程序的执行时间,是不太容易。 感谢两位关注。谢谢zhao4zhong1提供的方法。 之前的问题我找到原因了。 这是我在查到的资料,供后来者参考吧: clock()函数的功能: 这个函数返回从“开启这个程序进程”到“程序中调用C++ clock()函数”时之间的CPU时钟计时单元(clock tick)数当程序单线程或者单核心机器运行时,这种时间的统计方法是正确的。但是如果要执行的代码多个线程并发执行时就会出问题,因为最终end-begin将会是多个核心总共执行的时钟嘀嗒数,因此造成时间偏大。 Linux下也可直接使用time命令。
cbzjzsb123 2012-12-11
  • 打赏
  • 举报
回复
将待测程序段循环足够多次,手动掐秒表计时可能更准确。
赵4老师 2012-12-11
  • 打赏
  • 举报
回复
提醒: 使用电脑计时有时误差会很大,因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次,手动掐秒表计时可能更准确。
赵4老师 2012-12-11
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <io.h>
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  _vsnprintf         vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
char logstr[16000];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
            flog=fopen(logfilename1,"a");
            if (NULL==flog) return;
        }
        fclose(flog);
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
    int i;
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
#else
    pthread_mutex_init(&cs_log,NULL);
#endif
    for (i=0;i<10000;i++) {
        Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
    }
#ifdef WIN32
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
操作系统实验报告 实验名称: 线程控制实验 计算机科学与技术学院 目录 一、实验目的和要求 2 二、实验内容 2 三、实验步骤 2 四、实验结果与分析 3 1.单线程 3 2.单线程(睡眠4s) 3 3.多线程 4 4.多线程(每个子线程睡眠1s) 4 5.单线程与多线程对比 5 五、程序源代码 5 1.单线程实验代码 5 2.单线程实验代码 6 六、实验体会 7 一、实验目的和要求 通过本实验掌握在Linux操作系统中遵循Posix线程标准接口进行多线程程序编程,熟练掌握线程的创建pthread_create(),线程的终止pthread_exit(),等待线程合并pthread_join()等线程控制操作,利用信号量或者互斥锁实现线程建的同步。 二、实验内容 问题:求1000000个浮点数(精确到小数点后4位)的平均值(和,最大值,最小值),具体的问题描述流程图如下图图1所示: 三、实验步骤 1、随机生成1000000个浮点数; 2、创建4个子线程,分别求250000个浮点数之和; 3、完成1000000个浮点数之和并打印结果; 4、统计多线程并发执行完成计算的时间; 5、写一个单线程程序,同样完成1000000个随机数求和的计算,统计计算时间,并和前面结果进行对比; 操作系统实验报告-全文共5页,当前为第1页。6、让单线程程序睡眠四秒钟、多线程程序各子程序睡一秒的条件下(两个程序总的睡眠时间相同),对比执行结果; 操作系统实验报告-全文共5页,当前为第1页。 7、分析两次对比结果的差异,写出自己的见解。 四、实验结果与分析 1、单线程完成1000000个浮点数的求和运算所用的时间情况如下图图2所示: 图2 单线程计算时间 分析:实验中每次随机产生一个0到1之间的浮点数,1000000个这样的数相加的话的平总和大概就在500000左右(按照随机数的平均值原理),实验中sum=499919.3750,显然结果正确,整个计算运行时间为0.1086s。 2、单线程完成1000000个浮点数的求和运算,单线程中睡眠4秒钟,所用的时间情况如下图图3所示: 图3 单线程计算时间(睡眠4秒) 分析:根据上一次单线程的执行情况来看,这一次让单线程睡眠4秒钟,最后执行时间刚好就是4秒加上计算时间。也就是说计算1000000个浮点数的总和平均时间约为0.1s。 3、四个子线程共同完成1000000个浮点数的求和计算所用时间情况如下图图4所示: 图4 多线程计算时间 分析:因为这次是4个子线程并发运行,每个子线程只需计算250000个浮点数的总和,理想情况下这时候的运行时间应该是这单线程中计算时间的四分之一。从图中可以看到执行时间是0.0233s,很显然这个时间约为单线程求1000000个浮点数之和的时间(0.1086)的四分之一,符合预期的结果。 4、四个子线程共同完成1000000个浮点数的求和计算,其中每个子线程睡眠1秒钟,最终所用时间情况如下图图5所示: 图5 多线程计算时间(每个子线程睡眠1秒) 分析:这里四个子线程每个子线程睡眠一秒,但由于四个子线程并发同步的在执行,当一个子线程在睡眠时,另外一个子线程却仍然在继续求和计算,因此他们一起合作同步完成1000000个浮点数的计算所需的时间就是1秒加上上图中不睡眠的时候的计算时间。从图中可以看到1.0261s 1s+0.0233s,所以最终的结果符合预期值。 5、单线程计算时间(睡眠4s)与多线程计算时间(每个子线程睡眠1s)对比效果如下图图6所示: 图6 单线程 (睡眠4s)与多线程 (每个子线程睡眠1s)计算时间对比图 五、程序源代码 /************************* *FileName:signal_thread.c *Author: *Date:2013/11/22 ***************************/ #include #include #include thread.h> #include #include #define LOOP 1000000 float SUM=0; void *ADD() { int i; srand(time(NULL)); 操作系统实验报告-全文共5页,当前为第2页。 for(i=0;ithread_t p; int result; float time; struct timeval start; struct

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧