2013-12-14 3 views
0

У меня есть тестовая программа, которая выполняет следующие на основе параметров командной строки:Mutiproccess IO быстрее многопоточных IO

1) вилка нескольких процессов, и каждый процесс полностью читает тот же текстовый файл последовательно

2) создают несколько потоков, и каждый поток полностью читает один и тот же текстовый файл последовательно

Я заметил, что многопоточный подход занимает около 35% больше времени, чем многопроцессорный подход.

Почему многопроцессорный IO быстрее, чем mutithreaded IO?

машины конфигурации: 8 ГБ оперативной памяти, 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

real 0m26.170s пользователь 1m40.149s SYS 0m3.360s

Время, затраченное на многопоточных:

времени ./io_test т 20

реальные 0m35.561s пользователя 2m14.245s SYS 0m4.577s

+0

Я предполагаю, что 'ifstream' должен использовать блокировки при многопоточности. Если это правильно, то в файле с более длинными строками разница будет меньше. – zch

ответ

0

Я подозреваю, что вы тестируете это на каком-то современном настольном Linux-дистрибутиве с настройками ввода-вывода ядра по умолчанию - и это, когда я подозреваю, что ответ будет найден.

  • Различные процессы имеют разные contextes ввода-вывода, так что ИО для каждого контекста является строго последовательным
  • Различные потоки совместно IO контекст их родительского процесса, так что если различные потоки сделать различные прогресс (что неизбежно с 4 ядрами и 20 потоков), IO рандомизируется путем чередования последовательных чтений из разных положений
+0

В многопроцессорном подходе также, поскольку я работаю на 4-ядерном компьютере с 20 процессами, каждый процесс будет иметь разный прогресс и когда они запросят чтение диска, не приведет ли это к случайному IO? – user2187598

+0

Это рандомизация IO ** в том же контексте **, которая здесь важна! Это наихудший вариант для логики лифта. –

Смежные вопросы