2

所以我在计算每个线程的线程函数的运行时间时遇到问题,我需要能够找到所有线程的总运行时间,但它没有正确执行。(见代码下面的输出)

#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 %f\n", n, totalintegral);
    fflush(stdout);
    printf("no lock completed in %f\n", 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 %f\n",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 是我的变量,它存储经过的总时间。我猜为什么这不起作用是因为小数点超出范围,但它不应该吗?

4

3 回答 3

2

如果您调用clock()您的系统,它的分辨率为 10 毫秒。因此,如果一个进程需要 2 毫秒,那么它通常会报告 0.00 秒或 0.01 秒的时间,这取决于你无法控制的一堆事情。

请改用其中一个高分辨率时钟。可以用clock_gettimeCLOCK_THREAD_CPUTIME_IDCLOCK_PROCESS_CPUTIME_ID相信这个时钟的分辨率比 好几个数量级clock()

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

于 2012-11-04T22:47:06.933 回答
1

最有可能的是,您的时钟滴答对于您尝试测量的经过时间来说太粗糙了。大多数开始和停止时钟是相同的。偶尔,在您的线程执行期间发生时钟滴答,您会看到 1 个滴答。(这实际上是迪特里希上面所说的)。

举例说明这意味着什么,假设您的线程需要一个小时才能完成,而您的时钟每天在午夜滴答一次。大多数情况下,当您运行线程时,线程会在同一天开始和结束。但是,如果您碰巧在午夜后的一个小时内运行它,您将看到不同日期的开始和停止(1 个滴答声)。那么你需要的是一个更快的时钟,但这样的时钟很可能不可用。

于 2012-11-04T22:36:29.650 回答
0

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

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

这是两个完全不同的东西。也许您的线程不会占用太多处理器时间。

于 2012-11-04T23:07:44.033 回答