Производитель-Потребитель, использующий OpenMP-Задачи

Я пытаюсь реализовать параллельный алгоритм, используя задачи в OpenMP. Шаблон параллельного программирования основан на идее производителя-потребителя, но, поскольку процесс потребления медленнее, чем производитель, я хочу использовать несколько производителей и несколько потребителей. Основная идея состоит в том, чтобы создать столько потоков ОС, сколько производителей, и тогда каждый из них будет создавать задачи, которые должны выполняться параллельно (потребителями). Каждый производитель будет связан с пропорциональным числом потребителей (т.е. numCheckers / numSeekers). Я'm работает на двухчиповом сервере Intel с 6 ядрами на чип. Дело в том, что когда я использую только одного производителя (ищущего) и все большее число потребителей (контролеров), производительность очень быстро снижается по мере роста числа потребителей (см. Таблицу ниже), даже если на определенном уровне работает правильное количество ядер. 100%. С другой стороны, если я увеличу количество производителей, среднее время уменьшится или, по крайней мере, останется стабильным даже при пропорциональном количестве потребителей. Мне кажется, что все усовершенствования сделаны разделением входов между производителями, и задачи только ошибаются. Но опять же я неНе может быть никакого объяснения поведению с одним производителем. Я что-то упускаю в логике OpenMP-Task? Я делаю что-то неправильно?

-------------------------------------------------------------------------
|   producers   |   consumers   |   time        |
-------------------------------------------------------------------------
|       1       |       1       |   0.642935    |
|       1       |       2       |   3.004023    |
|       1       |       3       |   5.332524    |
|       1       |       4       |   7.222009    |
|       1       |       5       |   9.472093    |
|       1       |       6       |   10.372389   |
|       1       |       7       |   12.671839   |
|       1       |       8       |   14.631013   |
|       1       |       9       |   14.500603   |
|       1       |      10       |   18.034931   |
|       1       |      11       |   17.835978   |
-------------------------------------------------------------------------
|       2       |       2       |   0.357881    |
|       2       |       4       |   0.361383    |
|       2       |       6       |   0.362556    |
|       2       |       8       |   0.359722    |
|       2       |      10       |   0.358816    |
-------------------------------------------------------------------------

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

int main( int argc, char** argv) {

  // ... process the input (read from file, etc...)

  const char *buffer_start[numSeekers];
  int buffer_len[numSeekers];

  //populate these arrays dividing the input
  //I need to do this because I need to overlap the buffers for
  //correctness, so I simple parallel-for it's not enough 

  //Here is where I create the producers
  int num = 0;
  #pragma omp parallel for num_threads(numSeekers) reduction(+:num)
  for (int i = 0; i < numSeekers; i++) {
      num += seek(buffer_start[i], buffer_len[i]);
  }

  return (int*)num;
}

int seek(const char* buffer, int n){

  int num = 0;

  //asign the same number of consumers for each producer 
  #pragma omp parallel num_threads(numCheckers/numSeekers) shared(num)
  {
    //only one time for every producer
    #pragma omp single
    {
      for(int pos = 0; pos < n; pos += STEP){
    if (condition(buffer[pos])){
      #pragma omp task shared(num)
      {
        //check() is a sequential function
        num += check(buffer[pos]);
      }
    }
      }
      #pragma omp taskwait
    }
  return num;
}

Ответы на вопрос(2)

Ваш ответ на вопрос