Actualmente estoy paralelizando el programa usando openmp en un fenómeno de 4 núcleos. Sin embargo, noté que mi paralelización no hace nada por el rendimiento. Naturalmente, asumí que me perdí algo (intercambio de falsos, serialización a través de bloqueos, ...), sin embargo, no pude encontrar algo así. Además de la utilización de la CPU, parecía que el programa se ejecutó solo en un núcleo. De lo que encontré sched_getcpu()
debería darme el ID del núcleo en el que está actualmente programado el hilo que está ejecutando la llamada. Así que escribí el siguiente programa de prueba:Hilos OpenMP ejecutándose en el mismo núcleo de la CPU
#include <iostream>
#include <sstream>
#include <omp.h>
#include <utmpx.h>
#include <random>
int main(){
#pragma omp parallel
{
std::default_random_engine rand;
int num = 0;
#pragma omp for
for(size_t i = 0; i < 1000000000; ++i) num += rand();
auto cpu = sched_getcpu();
std::ostringstream os;
os<<"\nThread "<<omp_get_thread_num()<<" on cpu "<<sched_getcpu()<<std::endl;
std::cout<<os.str()<<std::flush;
std::cout<<num;
}
}
En mi máquina esto da el siguiente resultado (los números aleatorios variarán por supuesto):
Thread 2 on cpu 0 num 127392776
Thread 0 on cpu 0 num 1980891664
Thread 3 on cpu 0 num 431821313
Thread 1 on cpu 0 num -1976497224
De esta Asumo que todos los hilos se ejecutan en el mismo núcleo (el que tiene id 0). Para estar más seguro, también probé el enfoque desde this answer. Los resultados fueron los mismos. Además, el uso de #pragma omp parallel num_threads(1)
no hizo que la ejecución fuera más lenta (de hecho, un poco más rápida), lo que dio credibilidad a la teoría de que todos los subprocesos utilizan la misma CPU, sin embargo, el hecho de que la CPU se muestra siempre como 0
me hace sospechar. Además, revisé GOMP_CPU_AFFINITY
que inicialmente no estaba configurado, así que intenté configurarlo en 0 1 2 3
, lo que debería vincular cada hilo a un núcleo diferente de lo que yo entiendo. Sin embargo, eso no hizo la diferencia.
Desde que desarrollo en un sistema de Windows, uso linux en virtualbox para mi desarrollo. Entonces pensé que tal vez el sistema virtual no podía acceder a todos los núcleos. Sin embargo, comprobar la configuración de virtualbox mostró que la máquina virtual debería obtener los 4 núcleos y ejecutar mi programa de prueba 4 veces al mismo tiempo parece usar los 4 núcleos a juzgar por la utilización de la CPU (y el hecho de que el sistema no respondía) .
Así que mi pregunta es básicamente qué está pasando exactamente aquí. Más al grano: ¿Debo deducir que todos los hilos utilizan el mismo núcleo correctamente? Si lo es, ¿cuáles podrían ser las razones de ese comportamiento?
heres un error común ¿configuró la variable de entorno OMP_NUM_THREADS = 4? – pyCthon
@pyCthon: 'OMP_NUM_THREADS' no parece estar configurado, sin embargo, como openmp crea 4 hilos, no creo que sea necesario. – Grizzly
raro, creo que podría ser algo con su máquina virtual Probé el mismo código incluso instalé utmpx.h y parecía funcionar bien en una máquina de 8 y 16 núcleos – pyCthon