多线程IO比多线程IO更快



我有一个测试程序,它根据命令行选项执行以下操作:

1) 分叉多个进程,每个进程完全按顺序读取相同的文本文件

2) 创建多个线程,每个线程按顺序完全读取相同的文本文件

我注意到多线程方法比多进程方法多花35%的时间。

为什么多进程IO比多线程IO更快?

机器配置:8GB 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.149ssys 0m3.360s

多线程所用时间:

时间/io_test t 20

实际0m35.561s用户2m14.245ssys 0m4.577s

我怀疑你在一些具有默认内核IO设置的现代桌面Linux发行版上测试了这一点,我怀疑答案就在这里。

  • 不同的进程有不同的IO上下文,因此每个上下文的IO都是严格顺序的
  • 不同的线程共享其父进程的IO上下文,因此,如果不同的线程取得不同的进展(这对于4个核心和20个线程来说是不可避免的),则通过交错从不同位置进行的顺序读取来随机化IO

最新更新