1

私はpthreadを使用してきましたが、1つのスレッドを使用する場合、またはタスクをNスレッドの1 / Nに分割する場合、コードが独立して同じ時間を要していることに気付きました。例として、コードを次の例に減らしました。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#include <boost/progress.hpp>

#define SIZEEXEC 200000000

using namespace boost;
using std::cout;
using std::endl;

typedef struct t_d{
   int  intArg;
} Thread_data;

void* function(void *threadarg)
{
    Thread_data *my_data= (Thread_data *) threadarg; 
    int size= my_data->intArg;

    int i=0;
    unsigned rand_state = 0;
    for(i=0; i<size; i++) rand_r(&rand_state);
    return 0;
}

void withOutThreads(void)
{
    Thread_data* t1= new Thread_data();
    t1->intArg= SIZEEXEC/3;
    function((void *) t1);

    Thread_data* t2= new Thread_data();
    t2->intArg= SIZEEXEC/3;
    function((void *) t2);

    Thread_data* t3= new Thread_data();
    t3->intArg= SIZEEXEC/3;
    function((void *) t3);    
}

void withThreads(void)
{
    pthread_t* h1 = new pthread_t;
    pthread_t* h2 = new pthread_t;
    pthread_t* h3 = new pthread_t;
    pthread_attr_t* atr = new pthread_attr_t;

    pthread_attr_init(atr);    
    pthread_attr_setscope(atr,PTHREAD_SCOPE_SYSTEM);

    Thread_data* t1= new Thread_data();
    t1->intArg= SIZEEXEC/3;
    pthread_create(h1,atr,function,(void *) t1);

    Thread_data* t2= new Thread_data();
    t2->intArg= SIZEEXEC/3;
    pthread_create(h2,atr,function,(void *) t2);

    Thread_data* t3= new Thread_data();
    t3->intArg= SIZEEXEC/3;
    pthread_create(h3,atr,function,(void *) t3);

    pthread_join(*h1,0);
    pthread_join(*h2,0);
    pthread_join(*h3,0);
    pthread_attr_destroy(atr);
    delete h1;
    delete h2;
    delete h3;
    delete atr;
}

int main(int argc, char *argv[])
{
    bool multThread= bool(atoi(argv[1]));

    if(!multThread){
        cout << "NO THREADS" << endl;
        progress_timer timer;
        withOutThreads();
    }
    else {
        cout << "WITH THREADS" << endl;
        progress_timer timer;
        withThreads();
    }

    return 0;
}

コードが間違っているか、システムに並列処理を許可していないものがあります。Ubuntu 11.10 x86_64-linux-gnu、gcc 4.6、Intel®Xeon(R)CPU E5620@2.40GHz×4で実行しています

アドバイスありがとうございます!

編集:答えを考えると、(1)progress_timerタイマーでは「リアルタイム」時間の差を測定できず、(2)「関数」で与えているタスクではマシンが十分ではないようです。 1つまたは3つのスレッドで異なる時間を与えます(これは奇妙なことですが、どちらの場合も約10秒かかります...)。私はメモリを割り当ててより重くしようとしましたが、そうです、違いがわかります。私の他のコードはもっと複雑ですが、それでも1つまたは3つのスレッドで同時に実行される可能性があります。ありがとう!

4

2 に答える 2

2

これは予期されることです。壁時間ではなく、CPU 時間を測定しています。

time ./test 1
WITH THREADS
2.55 s


real    0m1.387s
user    0m2.556s
sys     0m0.008s

リアルタイムはユーザー時間より短く、測定時間と同じです。実時間は壁時計が示すものであり、user と sys は 、すべての CPU を合わせたユーザー モードとカーネル モードで費やされた CPU 時間です。

time ./test 0
NO THREADS
2.56 s


real    0m2.578s
user    0m2.560s
sys     0m0.008s

測定時間、リアルタイム、ユーザー時間はすべて実質的に同じです。

于 2012-04-25T14:49:29.820 に答える
1

犯人はprogress_timerか、むしろそれを理解しているようです。

main() をこれに置き換えてみてください。これは、プログラムがprogress_timerによって報告されたように時間がかからないことを示しています。おそらく、合計システム時間を報告していますか?

#include <sys/time.h>
void PrintTime() {
    struct timeval tv;

    if(!gettimeofday(&tv,NULL))
        cout << "Sec=" << tv.tv_sec << " usec=" << tv.tv_usec << endl ;

}

int main(int argc, char *argv[])
{
    bool multThread= bool(atoi(argv[1]));

    PrintTime();
    if(!multThread){
        cout << "NO THREADS" << endl;
        progress_timer timer;
        withOutThreads();
    }
    else {
        cout << "WITH THREADS" << endl;
        progress_timer timer;
        withThreads();
    }
    PrintTime();

    return 0;
}
于 2012-04-25T14:44:25.913 に答える