A vue de nez, je pense qu'il y a deux problèmes ici:
La création d'un thread est coûteuse. La création de 16 threads est encore plus coûteuse. Donc pour des traitements aussi courts (dans ton cas de l'ordre de 400 us), la création des threads prend beaucoup trop de temps. Si tu utilises OpenMP, tu peux évaluer le coût de la création des threads en faisant plusieurs mesures à la suite:
A la première mesure, le runtime OpenMP va créer un certain nombre de threads et paralléliser la boucle. A la fin de cette boucle, les threads ne seront pas détruits, et normalement la deuxième boucle devrait aller plus vite (les threads sont réutilisés).
Donc si dans ton application tu risques de faire plusieurs fois ce calcul, essaie de prendre en compte la création/destruction des threads.
Le deuxième problème que je vois est lié aux caches. Quand tu alloues et initialises les tableaux yvar*, ils se retrouvent dans le cache d'un des cœurs. Quand tu lances un thread pour qu'il fasse une partie du calcul, il faut que les données qu'il traite soient envoyées dans le cache qui va bien.
Si ce thread est 'proche' du cache où sont les données, ca se passe bien, mais si il faut faire transiter les données d'un processeur à l'autre, ca prend beaucoup de temps.
En fixant tes threads de calcul à la main, tu devrais pouvoir maitriser un peu mieux ces transferts de données. Pour ca, tu peux utiliser hwloc ( http://www.open-mpi.org/projects/hwloc/ )
# creation des threads + cache
Posté par François Trahay . En réponse au message Parallelisation d'une boucle (théoriquement) trivialement parallélisable. Évalué à 4.
La création d'un thread est coûteuse. La création de 16 threads est encore plus coûteuse. Donc pour des traitements aussi courts (dans ton cas de l'ordre de 400 us), la création des threads prend beaucoup trop de temps. Si tu utilises OpenMP, tu peux évaluer le coût de la création des threads en faisant plusieurs mesures à la suite:
for (mesure=0; mesure<10; mesure++) {
start = get_time();
#pragma omp parallel for
for(i=0; i<N;i++) {
...
}
stop = get_time();
}
A la première mesure, le runtime OpenMP va créer un certain nombre de threads et paralléliser la boucle. A la fin de cette boucle, les threads ne seront pas détruits, et normalement la deuxième boucle devrait aller plus vite (les threads sont réutilisés).
Donc si dans ton application tu risques de faire plusieurs fois ce calcul, essaie de prendre en compte la création/destruction des threads.
Le deuxième problème que je vois est lié aux caches. Quand tu alloues et initialises les tableaux yvar*, ils se retrouvent dans le cache d'un des cœurs. Quand tu lances un thread pour qu'il fasse une partie du calcul, il faut que les données qu'il traite soient envoyées dans le cache qui va bien.
Si ce thread est 'proche' du cache où sont les données, ca se passe bien, mais si il faut faire transiter les données d'un processeur à l'autre, ca prend beaucoup de temps.
En fixant tes threads de calcul à la main, tu devrais pouvoir maitriser un peu mieux ces transferts de données. Pour ca, tu peux utiliser hwloc ( http://www.open-mpi.org/projects/hwloc/ )