Productor-Consumidor usando OpenMP-Tareas

Estoy tratando de implementar un algoritmo paralelo usando tareas dentro de OpenMP. El patrón de programación paralelo se basa en la idea productor-consumidor, pero como el proceso del consumidor es más lento que el productor, quiero utilizar algunos productores y varios consumidores. La idea principal es crear tantos subprocesos de sistema operativo como productores y luego cada uno de estos creará tareas que se realizarán en paralelo (por parte de los consumidores). Cada productor estará asociado con un número proporcional de consumidores (es decir, numCheckers / numSeekers). Estoy ejecutando el algoritmo en un servidor Intel de doble chip con 6 núcleos por chip. El problema es que cuando uso solo un productor (buscador) y un número creciente de consumidores (verificadores), el rendimiento decae muy rápidamente a medida que crece el número de consumidores (consulte la tabla a continuación), aunque la cantidad correcta de núcleos funciona a una 100%. Por otro lado, si incremento el número de productores, el tiempo promedio disminuye o al menos se mantiene estable, incluso con un número proporcional de consumidores. Me parece que toda la mejora se realiza mediante la división de la entrada entre los productores, y las tareas son solo errores. Pero una vez más, no tengo ninguna explicación para el comportamiento con un productor. ¿Me estoy perdiendo algo en la lógica de OpenMP-Task? ¿Estoy haciendo algo mal?

-------------------------------------------------------------------------
|   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    |
-------------------------------------------------------------------------

La sección principal de mi código es como en barbecho:

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;
}