0

コマンドラインオプションに基づいて次のことを行うテストプログラムがあります。

1)複数のプロセスをフォークし、各プロセスが同じテキストファイルを順番に完全に読み取ります

2) 複数のスレッドを作成し、各スレッドが同じテキスト ファイルを順番に完全に読み取る

マルチスレッド アプローチは、マルチプロセス アプローチよりも約 35% 長い時間がかかることに気付きました。

マルチプロセス IO がマルチスレッド IO よりも速いのはなぜですか?

マシン構成: 8 GB RAM、4 コア、

コードとテスト結果は次のとおりです。

using namespace std;
#include<fstream>
#include<iostream>
#include<pthread.h>
#include<errno.h>
#include<sys/wait.h>
#include <string>



void* run_thread(void * tmp)
{
    int counter=0;
    string s;
    string input_file("perf_input");
    ifstream in(input_file.c_str(), ios_base::in);
    while(getline(in, s))
    {
        counter++;
    }
    cout<<"counter "<<counter<<endl;
}

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        cout<<"Invalid number of arguments "<<endl;
        return -1;
    }


    if(argv[1][0] == 'p')
    {
        cout<<"fork process"<<endl;
        int n = atoi(argv[2]);
        cout<<" n " <<n<<endl;

        for(int i=0;i<n;i++)
        {
            int cpid = fork();

            if(cpid< 0)
            {
                cout<<"Fork failed "<<endl;
                exit(0);
            }
            else if(cpid == 0)
            {
                //child
                cout<<"Child created "<<endl;
                run_thread(NULL);
                cout<<"Child exiting "<<endl;
                exit(0);
            }
        }

        while (waitpid(-1, NULL, 0))
        {
            if (errno == ECHILD)
            {
                break;
            }
        }
    }
    else
    {
        cout<<"create thread"<<endl;
        int n = atoi(argv[2]);
        cout<<" n " <<n<<endl;

        pthread_t *tids = new pthread_t[n];
        for(int i=0;i <n; i++)
        {
            pthread_create(tids + i, NULL, run_thread, NULL);
        }

        for(int i=0;i <n; i++)
        {
            pthread_join(*(tids + i), NULL);
        }
    }
}

マルチプロセスにかかった時間:

時間 ./io_test p 20

実 0m26.170s ユーザー 1m40.149s システム 0m3.360s

マルチスレッドにかかった時間:

時間 ./io_test t 20

実際の 0m35.561s ユーザー 2m14.245s システム 0m4.577s

4

1 に答える 1

0

デフォルトのカーネル IO 設定を使用して、最新のデスクトップ Linux ディストリビューションでこれをテストしていると思われます。これが、答えが見つかると思われる場所です。

  • 異なるプロセスには異なる IO コンテキストがあるため、各コンテキストの IO は厳密にシーケンシャルです。
  • 異なるスレッドは親プロセスの IO コンテキストを共有するため、異なるスレッドが異なる進行をする場合 (4 コアと 20 スレッドでは避けられない)、IO は異なる位置からの順次読み取りをインターリーブすることによってランダム化されます。
于 2013-12-14T15:49:32.890 に答える