问题将PTHREADS的线程函数计时



,所以我正在遇到一个问题,计算每个线程的线程函数的经过的时间,我需要能够找到所有线程的总过去时间,但不是正确执行此操作。(请参阅下面的输出代码)

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <time.h>
int numthread;
double x1;
double x2;
double h; 
double totalintegral;
int n;              //number of trapezoids
int localn;
double gnolock;
double gmute;
double gbusy;
double gsema;
double doTrapRule(double localx1, double localx2, double h, int localn);
double doFunction(double x);
void *threadCalc(void* threadid);
int main(int argc, char * argv[])
{
    int i;
    x1 = 0.0;
    x2 = 20.0;
    n = 200000;
    numthread = 10;
    pthread_t* threads = malloc(numthread*sizeof(pthread_t));
    h = (x2 - x1)/n;
    localn = n/numthread;
    for(i = 0; i < numthread; i++)
    {
        pthread_create(&threads[i], NULL, (void *) &threadCalc, (void*) i);
    }
    for(i = 0; i < numthread; i++)
    {
        pthread_join(threads[i], NULL);
    }
    printf("Trap rule result with %d trap(s) is %fn", n, totalintegral);
    fflush(stdout);
    printf("no lock completed in %fn", gnolock);
    exit(0);
}
void *threadCalc(void* threadid)
{
    clock_t start = clock();
    double localx1;
    double localx2; 
    double localintegral;
    int cur_thread = (int)threadid;
    localx1 = x1 + cur_thread * localn * h;
    localx2 = localx1 + localn * h;
    localintegral = doTrapRule(localx1, localx2, h, localn);
    totalintegral = totalintegral + localintegral;
    //printf("Trap rule result with %d trap(s) is %f", n, totalintegral);
    clock_t stop = clock();
    double time_elapsed = (long double)(stop - start)/CLOCKS_PER_SEC;
    printf("time elapsed of each thread %fn",time_elapsed);
    gnolock = gnolock + time_elapsed;
    return NULL;
}

double doTrapRule(double localx1, double localx2, double h, int localn)
{
    //time start here
    double localtrapintegral;
    double tempx1;
    int i;
    localtrapintegral = (doFunction(localx1) + doFunction(localx2)) / 2.0;
    for(i = 1; i <= (localn - 1); i++)
    {
        tempx1 = localx1 + i * h;
        localtrapintegral = localtrapintegral + doFunction(tempx1);
    }
    localtrapintegral = localtrapintegral * h;
    //time end here, add elapsed to global
    return localtrapintegral;
}
double doFunction(double x)
{
    double result;
    result = x*x*x;
    return result;
}

输出:

time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.010000
time elapsed of each thread 0.010000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
Trap rule result with 200000 trap(s) is 40000.000001
no lock completed in 0.020000

您出于何种原因可以看到,只有线程实际上只返回时间。我多次运行了此操作,每次只有几个线程返回结果。就像FYI Gnolock是我的变量一样,它存储了经过的总时间。我猜到为什么这不起作用是因为小数点超出了范围,但不应该?

如果您在系统上调用clock(),则该分辨率为10 ms。因此,如果一个过程需要2 ms,则通常会报告0.00或0.01的时间,具体取决于您无法控制的一堆事情。

改用高分辨率时钟之一。您可以将clock_gettimeCLOCK_THREAD_CPUTIME_IDCLOCK_PROCESS_CPUTIME_ID一起使用,我相信该时钟的分辨率比clock()好几个数量级。

有关更多信息,请参见man 2 clock_gettime

很可能是您的时钟刻度太粗糙了,对于您试图测量的经过的时间。主要是开始和停止时钟相同。有时,偶然的时钟刻度在您的线程执行过程中会发生,您会看到1个滴答。(这实际上是Dietrich上面所说的)。

作为这意味着什么的一个例子,想象一下您的线程需要一个小时才能完成,并且每天午夜每天滴答一次。大多数情况下,当您运行线程时,启动并结束在同一天。但是,如果您碰巧在午夜的一个小时内运行它,您将在不同的日子(1个tick)看到开始并停止。然后您需要的是一个更快的时钟,但是这样的时钟很可能无法使用。

您正在使用错误的工具。clock不能测量经过的时间,但

clock()函数返回处理器时间的近似值 通过程序。

这是两个完全不同的事情。也许您的线程不会消耗太多的处理器时间。

最新更新