2016-03-07 3 views
1

Я бегу следующий код:пользователя в многопроцессорной работы

, когда я запускаю этот код с процессом 1 ребенок: я получаю следующую информацию о времени:

(я бегу с помощью/USR/бен/время ./job 1)

5.489u 0.090s 0: 05,58 99,8% (1 работа работает)

когда я бегу с 6 детей процессы: я получаю следующее

74.731u 0.692s 0 : 1 2,59 599,0% (6 рабочих мест, работающих параллельно)

Машина, на которой я запускаю эксперимент, имеет 6 ядер, 198 ГБ ОЗУ и ничего больше не работает на этой машине.

Я ожидал, что пользовательское время будет 6 раз в случае 6 заданий, работающих параллельно. Но это намного больше (13,6 раза). Мои вопросы: откуда это время увеличивается? Это связано с тем, что несколько ядер перескакивают из одного места памяти в другое чаще в случае выполнения 6 заданий параллельно? Или что-то еще мне не хватает.

Благодаря

#define MAX_SIZE 7000000 
#define LOOP_COUNTER 100 

#define simple_struct struct _simple_struct 
simple_struct { 
    int n; 
    simple_struct *next; 
}; 

#define ALLOCATION_SPLIT 5 
#define CHAIN_LENGTH 1 
void do_function3(void) 
{ 
    int i = 0, j = 0, k = 0, l = 0; 
    simple_struct **big_array = NULL; 
    simple_struct *temp = NULL; 

    big_array = calloc(MAX_SIZE + 1, sizeof(simple_struct*)); 


    for(k = 0; k < ALLOCATION_SPLIT; k ++) { 
     for(i =k ; i < MAX_SIZE; i +=ALLOCATION_SPLIT) { 
      big_array[i] = calloc(1, sizeof(simple_struct)); 
      if((CHAIN_LENGTH-1)) { 
       for(l = 1; l < CHAIN_LENGTH; l++) { 
        temp = calloc(1, sizeof(simple_struct)); 
        temp->next = big_array[i]; 
        big_array[i] = temp; 
       } 
      } 
     } 
    } 

    for (j = 0; j < LOOP_COUNTER; j++) { 
     for(i=0 ; i < MAX_SIZE; i++) { 
      if(big_array[i] == NULL) { 
       big_array[i] = calloc(1, sizeof(simple_struct)); 
      } 
      big_array[i]->n = i * 13; 
      temp = big_array[i]->next; 
      while(temp) { 
       temp->n = i*13; 
       temp = temp->next; 
      } 
     } 
    } 
} 

int main(int argc, char **argv) 
{ 
    int i, no_of_processes = 0; 
    pid_t pid, wpid; 
    int child_done = 0; 
    int status; 
    if(argc != 2) { 
     printf("usage: this_binary number_of_processes"); 
     return 0; 
    } 

    no_of_processes = atoi(argv[1]); 

    for(i = 0; i < no_of_processes; i ++) { 
     pid = fork(); 

     switch(pid) { 
      case -1: 
       printf("error forking"); 
       exit(-1); 
      case 0: 
       do_function3(); 
       return 0; 
      default: 
       printf("\nchild %d launched with pid %d\n", i, pid); 
       break; 
     } 
    } 

    while(child_done != no_of_processes) { 
     wpid = wait(&status); 
     child_done++; 
     printf("\nchild done with pid %d\n", wpid); 
    } 

    return 0; 
} 
+0

Являются ли процессоры, использующие пропускную способность памяти? – user3528438

ответ

2

Во-первых, ваш тест является немного необычным. Как правило, при сопоставлении параллельных приложений можно сравнить две реализации:

  • Версия одного потока, решающая проблему размера S;
  • Многопоточная версия с N потоками, совместно решающая проблему размера S; в вашем случае, каждый из которых решает проблему размера S/N.

Затем вы делите время выполнения, чтобы получить speedup.

Если убыстрение является:

  • Около 1: параллельная реализация имеет аналогичные показатели как единственная реализация потоков;
  • Более 1 (обычно между 1 и N), распараллеливание приложения увеличивает производительность;
  • Менее 1: распараллеливание приложения ухудшает производительность.

Влияние на производительность зависит от целого ряда факторов:

  • Как хорошо ваш алгоритм может быть распараллеливание. См. Amdahl's law. Здесь не применяется.
  • Накладные расходы в межпоточной связи. Здесь не применяется.
  • Накладные расходы в межпоточной синхронизации. Здесь не применяется.
  • Конфликт за ресурсы ЦП. Здесь не следует применять (поскольку число потоков равно числу ядер). Однако HyperThreading может повредить.
  • Конфликт для кэшей памяти. Поскольку потоки не используют память, это уменьшит производительность.
  • Конфликт для доступа к основной памяти. Это снизит производительность.

Вы можете измерить последние 2 с помощью profiler. Посмотрите на пропуски кеша и заторможенные инструкции.

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