Attualmente sto parallelizzando il programma utilizzando openmp su un phenom2 a 4 core. Tuttavia ho notato che la mia parallelizzazione non fa nulla per la performance. Naturalmente ho pensato che mi mancasse qualcosa (falsesharing, serializzazione tramite serrature, ...), tuttavia non sono riuscito a trovare nulla di simile. Inoltre dall'utilizzo della CPU sembrava che il programma fosse eseguito su un solo core. Da quello che ho trovato sched_getcpu()
dovrei darmi l'Id del core al thread in cui è attualmente pianificata la chiamata. Così ho scritto il seguente programma di test:Thread OpenMP in esecuzione sullo stesso core 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;
}
}
Sulla mia macchina questo dà il seguente risultato (i numeri casuali varieranno ovviamente):
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
Da questo suppongo che tutti i thread eseguono sul stesso core (quello con id 0). Per essere più certi ho anche provato l'approccio da this answer. I risultati dove lo stesso. Inoltre, l'utilizzo di #pragma omp parallel num_threads(1)
non ha rallentato l'esecuzione (leggermente più veloce di fatto), dando credibilità alla teoria che tutti i thread utilizzano la stessa CPU, tuttavia il fatto che la CPU sia sempre visualizzata come 0
mi rende piuttosto sospetto. Inoltre ho controllato GOMP_CPU_AFFINITY
che inizialmente non era impostato, quindi ho provato a impostarlo su 0 1 2 3
, che dovrebbe legare ogni thread a un core diverso da quello che ho capito. Tuttavia ciò non ha fatto la differenza.
Da quando si sviluppa su un sistema Windows, io uso linux in virtualbox per il mio sviluppo. Quindi pensavo che forse il sistema virtuale non potesse accedere a tutti i core. Tuttavia, controllando le impostazioni di virtualbox è emerso che la macchina virtuale dovrebbe acquisire tutti e 4 i core ed eseguire il mio programma di test 4 volte allo stesso tempo sembra utilizzare tutti e 4 i core a giudicare dall'utilizzo della CPU (e dal fatto che il sistema stava diventando molto poco reattivo) .
Quindi per la mia domanda è fondamentalmente cosa sta succedendo esattamente qui. Più precisamente: La mia deduzione è che tutti i thread utilizzano lo stesso core correttamente? Se lo è, quali potrebbero essere le ragioni di tale comportamento?
heres un errore comune hai impostato la variabile di ambiente OMP_NUM_THREADS = 4? – pyCthon
@pyCthon: 'OMP_NUM_THREADS' non sembra essere impostato, tuttavia dal momento che openmp crea 4 thread non credo che sarebbe necessario. – Grizzly
strano penso che potrebbe essere qualcosa con la tua macchina virtuale ho provato lo stesso codice anche installato utmpx.h e sembrava funzionare bene su un 8 e un 16 core macchina – pyCthon