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

ご覧のとおり、何らかの理由で、実際に時間を返しているのはスレッドの 1 つだけです。これを複数回実行しましたが、毎回少数のスレッドのみが結果を返しました。参考までに、gnolock は経過時間の合計を格納する変数です。これが機能しない理由は、小数点が範囲外であるためだと思いますが、そうすべきではありませんか?

4

3 に答える 3

2

システムを呼び出す場合clock()、解像度は 10 ミリ秒です。そのため、プロセスに 2 ミリ秒かかる場合、通常、制御できない一連の事柄に応じて、0.00 秒または 0.01 秒の時間が報告されます。

代わりに、高解像度クロックの 1 つを使用してください。またはとclock_gettime一緒に使用できます。このクロックの分解能は より数桁優れていると思います。CLOCK_THREAD_CPUTIME_IDCLOCK_PROCESS_CPUTIME_IDclock()

詳細については、を参照man 2 clock_gettimeしてください。

于 2012-11-04T22:47:06.933 に答える
1

最も可能性が高いのは、測定しようとしている経過時間に対して時計の目盛りが粗すぎることです。ほとんどの場合、開始クロックと停止クロックは同じです。時折、スレッドの実行中にクロック ティックが発生し、1 ティックが表示されることがあります。(これは事実上、ディートリッヒが上で言ったことです)。

これが何を意味するかの例として、スレッドが完了するまでに 1 時間かかり、時計が 1 日 1 回、真夜中に時を刻むとします。ほとんどの場合、スレッドを実行すると、同じ日に開始および終了します。しかし、真夜中の 1 時間以内に実行すると、開始日と終了日が異なる日 (1 ティック) に表示されます。その場合に必要なのはより高速なクロックですが、そのようなクロックは利用できない可能性があります。

于 2012-11-04T22:36:29.650 に答える
0

間違ったツールを使用しています。clock経過時間は計測しませんが、

clock() 関数は、プログラムが使用するプロセッサー時間の概算を返します。

これらは2つの完全に異なるものです。おそらく、あなたのスレッドはプロセッサー時間をあまり使い果たしていないでしょう。

于 2012-11-04T23:07:44.033 に答える