Y as tbb ou QtConcurrent vue que tu utilise Qt.
SInon, je suis étonné pour ton prblème. Tu es sur de ne pas avoir oublié quelquechose lors du build?
Version imprimable
as tu essayé de recompiler pthread?
as tu essayé un de ces version de mingw?
http://www.tdragon.net/recentgcc/
Pour dire la verité je crois que j'ai tout essayé. J'ai essayé la dernier distib de TDM. J'ai effectivement recompilé pthread. J'ai linker ce bout de code avec les lib static de openMP et pthread. J'ai réessayé avec les DLLs. Gcc4.3.3, gcc4.4.0 et le dernier 4.4.2.
Voila là je suis sec. J'ai bien essayé de recompiler la lib openMP, histoire d'avoir une version debug. Mais là c'est trop difficile, je n'y arrive pas.
je suis super etonné que personne n'est rencontré ce type de soucie avant moi. openMP semble etre quelquechose de trés diffusé et utilisé...
J'avais pas vu tes suggestions de remplacement.J 'utilise deja QConcurrent, mais ca demande de réecrire énormément de chose, de plus j'ai une bonne partie des calculs ecrit en fortran. Je ne connaissais pas tbb, mais je ne sais pas si c'est free et si ca supporte le fortran. Malheureusement, j'ai investi pas mal de temps sur openMP sous la version linux, persuoidé que le portage sous windows serait aussi aisé que pour Qt par example.
openmp semble bien marcher sous visual. Mais uniquement les version payante...
Bon, j'essaye de m'en sortir autrement en remplaceant mon pTHread par une section openMP, mais je n'y arrive pas. Je fais cela :
Ce que je ne comprend pas, c'est que je n'atteind la sortie qu'a la fin de mon gros calcul alors que j'ai mis la directive nowait.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 #pragma omp parallel num_threads(1) { #pragma omp sections nowait { #pragma omp section { // mon gros calcul } } } printf("sortie\n");
Quelque chose m'échappe...
j'ai recompilé openMP avec ton projet mais je ne trouve pas ou est le probleme, j'ai une callstack un peu fantaisiste sous windows. j'ai du faire a la main le configure et je ne pense pas que j'aie tout mis correctement.
Peux-tu etre plus explicite. Qu'entends tu pas recompiler le projet. Veux-tu dire que tu as recompilé les source de openMP ?
Dans ce cas mon example initial ne plante plus ?
As-tu un make file pour compiler openMP, comment as-tu fais ?
j'ai pris les sources de OpenMP et un makefile, j'ai bricolé les fichiers que le script configure est censé créer. j'ai écrit un makefile qui compile ton appli et tous les fichiers de OpenMP.
au début ca plantait au meme endroit exactement, j'ai réussi a aller un poil plus loin mais la je ne sais pas du tout ou ca plante. Ca plante toujours par contre.
Dés fois ca part en boucle infinie (on dirait), des fois ca plante immédiatement (sans faire le premier printf, on dirait) et dés fois ca plante au meme endroit que toi. cest tres tres instable quoi.
Pourrais-tu me mettre ton make file histoire d'avoir un point de depart.
Ou as-tu eu les source de openMP
Merci d'avance
Bon j'ai finit pas compiler moi même openMP et je vois que ca plante dans la parce que la fonction de pthread , pthread_getspecific(...), renvoie un pointeur null.
Cette fonction appelant simplement la fonction windows api : TlsGetValue(...) qui renvoie donc un pointeur null.
Tout ca pour info, parce je ne vais pas m'amuser à debugger les fonctions API Windows.
tu peux compiler avec le support du mot-clé __thread (dans config.h, active HAVE_TLS)
active aussi HAVE_SYNC_BUILTINS et ajoute -march=i686 sur la ligne de commande pour la lib.
Je n'ai pas compris ou mettre le __thread
Ensuite si je met HAVE_SYNC_BUILTINS j'ai les erreurs de link suivantes:
Finallement as-tu réussi à faire fonctionner mon petit example ?
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 obj\Debug\gcc-4.4.2\libgomp\config\posix\bar.o||In function `gomp_barrier_wait_end':| D:\temp\gcc-4.4.2\libgomp\config\posix\bar.c|93|undefined reference to `__sync_add_and_fetch_4'| obj\Debug\gcc-4.4.2\libgomp\config\posix\bar.o||In function `gomp_team_barrier_wait_end':| D:\temp\gcc-4.4.2\libgomp\config\posix\bar.c|153|undefined reference to `__sync_add_and_fetch_4'| obj\Debug\gcc-4.4.2\libgomp\critical.o||In function `GOMP_critical_name_start':| D:\temp\gcc-4.4.2\libgomp\critical.c|72|undefined reference to `__sync_val_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\iter.o||In function `gomp_iter_dynamic_next':| D:\temp\gcc-4.4.2\libgomp\iter.c|192|undefined reference to `__sync_fetch_and_add_4'| D:\temp\gcc-4.4.2\libgomp\iter.c|238|undefined reference to `__sync_val_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\iter.o||In function `gomp_iter_guided_next':| D:\temp\gcc-4.4.2\libgomp\iter.c|323|undefined reference to `__sync_val_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\parallel.o||In function `gomp_resolve_num_threads':| D:\temp\gcc-4.4.2\libgomp\parallel.c|88|undefined reference to `__sync_val_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\single.o||In function `GOMP_single_start':| D:\temp\gcc-4.4.2\libgomp\single.c|46|undefined reference to `__sync_bool_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\work.o||In function `free_work_share':| D:\temp\gcc-4.4.2\libgomp\work.c|150|undefined reference to `__sync_bool_compare_and_swap_4'| obj\Debug\gcc-4.4.2\libgomp\work.o||In function `gomp_work_share_end_nowait':| D:\temp\gcc-4.4.2\libgomp\work.c|254|undefined reference to `__sync_add_and_fetch_4'| ||=== Build finished: 10 errors, 0 warnings ===|
Ok...
Juste avec l'option HAVE_TLS, ca semble fonctionner maintenant, tant que je n'essaye pas de preciser un nombre de thread superieur à 2 (j'ai 2 cores)
Si j'essaye 4 par example avec omp_set_num_threads(4) , j'obtiens 2 message "Hello, world in thread" avant un blocage ou un plantage, cest selon...
Ca progresse tout de même avec ton aide
tu as mis aussi -march=i686 sur la ligne de commande ? pour tes erreurs de link.
Pour le TLS, c'est deja bon.
J'ai repéré une erreur (enfin, selon moi c'est une erreur) dans une de leurs fonctions, dans team.c, dans gomp_team_start (ligne 250 a peu pres)
a la ligne 391 chez moi, ils créent les parametres de thread sur la pile avec
puis ils lancent les threadsCode:
1
2
3 start_data = gomp_alloca (sizeof (struct gomp_thread_start_data) * (nthreads-i));
ces parametres sont detruits a la fin de la fonction, puisqu'ils sont sur la pile. Or, rien ne garantit que les threads que l'on vient de créer aient fini de faire leur affaire avec ces parametres.
Essaye de remplacer gomp_alloca par gomp_malloc
ca crée un leak mémoire, ce n'est pas vraiment le top, mais c'est juste pour voir si l'erreur vient de la
Ok merci, ca ne change rien.
Pourrais me mettre une copie de ton "config.h" parce qu'en fait je ne passe pas par le makefile (quelles commandes mes tu à ton make file).
Pour le moment HAVE_SYNC_BUILTINS génére tj des erreurs au linkage
mon config.h est tout pourri, j'arrive pas aussi loin que toi (je l'ai bidouillé a la paluche aussi)
pour les erreurs de link c'est la ligne de commande de GCC qu'il faut changer pour éviter les erreurs. Dans le Makefile je compile simplement avec
Code:gcc -g -O0 -march=i686
Oui, c'est un peu bricolage pour le moment.
Bon je n'ai plus d'erreur de link et ca semble fonctionner avec mon code. Je fais bien des calculs en // Mais à la sortie de mon thread principale j'ai des plantage aleatoire dans la fonction (team.c):
static void gomp_free_thread (void *arg __attribute__((unused)))
Alors parfois c'est au début parce que thr vaut n'importe quoi (style "ffeeeffeee")
parfois c'est plus loing dans la fonction. Je vais voir si c'est possible de la blinder un peu mais qunad un pointer n'est pas vraiment NULL, je ne sais pas trop comment le tester
Encore plus etrange, cette fonction ne semble etre appelé que pour la fin de mon thread principale. Si je la vide avec un return tout semble fonctionner sauf qu'a chaque nouveau calcul je vois dans le programmemanger de windows que mon appli s'est incrementer d'un thread. Si j'inclu pas le mode openMP et la lib correspondante dans mon appli tout se passe correctement. Comme si la lib openMP avait remplacer la fonction charger de liberer les thread
feeefeee ca veut dire que la mémoire a été libérée par windows, et remplie par ce pattern pour bien montrer que c'est pas tres tres catholique de lire a cette adresse. Apparemment un thread un peu trop zélé a libérer la mémoire en question.