Pourquoi le fait que le système Léopard serait "optimisé" pour les processeurs multi-coeurs causerait-il un problème?
Et le gestionnaire des tâches de MacOS, il te montre bien les 2 coeurs du CPU?
Encore un peu et tu te convertiras à Windows ;-)
Version imprimable
Pourquoi le fait que le système Léopard serait "optimisé" pour les processeurs multi-coeurs causerait-il un problème?
Et le gestionnaire des tâches de MacOS, il te montre bien les 2 coeurs du CPU?
Encore un peu et tu te convertiras à Windows ;-)
Leopard est le prochain systeme macosx...
communiquer qu'il gere mieux le multi-core (processor affinity algorithms to make better use of multiple cores ... Also, POSIX thread allocation has been optimized to support the new NSOperation APIs.)
me parait enormement bizarre.
a mon avis, mon probleme vient du fait que macosx ne repartit pas les threads sur les deux coeurs differents... voila pourquoi je n'aurais pas de speed-up ...
ce n'est que de la supposition mais je sens ca gros comme une maison ([TROLL]a bas les constructeurs de maison[/TROLL])
a voir donc...
je ne pense plus que j'ai encore des choses à tester... si ?
cool que tu aies maintenant une version macosx qui tourne bien :-)
... et non windows j'en suis revenu !!! je ne repars plus :-D
ou sinon sur Linux :mouarf:
[EDIT] oui je vois les deux coeurs dans macosx
[EDIT] faute d'orthographe :aie:
T'aurais une idée comment tester le load balancing sur les cores ?
J'aimerais aussi le tester avec autre chose que les pthread, Openmp et Genial etant basés dessus, je ne peux verifier si c'est pthread ou le mac qui est en cause...
Tu veux dire la répartition de la charge sur les différents coeurs?Citation:
Envoyé par epsilon68
Non pas vraiment:
-sous Windows, le gestionnaire de tâche pour se faire une idée. Mais ça ne donne pas vraiment le taux d'occupation des coeurs, c'est par exemple souvent à 100% alors que le processeur est en attente des données.
-le petit programme allemand pour Windows ci-joint donne des courbes correspondant au taux réel d'occupation. Ca marche bien sur les Pentium4, mais je ne sais pas si il marche pour les processeurs CoreDuo.
Mais c'est après tout pas si utile que ça de connaître la charge pour mon programme, puisqu'il subdivise les calculs avec une granularité assez fine pour que les charges se répartissent assez uniformément, même si d'autres programmes sont exécutés en parallèle.
J'y ai un peu réfléchi aussi.Citation:
Envoyé par epsilon68
Il existe visiblement une librairie de multi-threading propre aux macs, tout comme il en existe une sous Windows (tu as sûrement remarqué l'implémentation basée sur cette librairie windows dans le fichier 'threads.h').
Ca suppose une implémentation de toutes les classes basiques (mutex, condition, sémaphore...) Je n'ai aucun moyen de le tester, et donc si tu veux utiliser cette possibilité, je ne pourrais que te seconder.
Je crois bien que Boost fait appel à cette librairie de MacOs, c'est donc probablement une bonne idée de regarder le code source pour avoir une bonne idée de son utilisation
Après avoir trouvé les références de l'API MacOS, j'ai programmé des classes utilisant la librairie de MacOS plutôt que pthreads.
(dans la clause MPTASKS du fichier 'threads.h')
Je n'ai aucun moyen de le tester, j'ai fait aussi attention que possible mais il y a peut-être quelques erreurs de compilation, voir même des bugs.
En tout cas une fois tous les problèmes éventuels corrigés, on devrait être fixé sur le multi-threading des Macs.
Remplace les 3 fichiers sources ci-joints.
... bon ca compile pas du tout :aie:
il faut que je regarde plus en details, et aussi la compilation avec les bundles.
a+
Flute!Citation:
Envoyé par epsilon68
Voici la doc que j'ai trouvé sur le multi-threading de macOS.Citation:
Envoyé par epsilon68
http://developer.apple.com/documenta...reference.html
Mais si je peux aider...
Hello? Pas de nouvelles?
Passe moi les erreurs de compilations, je pourrai peut-être corriger ce qui ne va pas.
Sinon, je pense que je vais te demander de faire d'autres benchmarks dans les jours à venir. J'ai peut-être encore le moyen d'améliorer la vitesse de mon implémentation sur ton Core2Duo: En utilisant certaines instructions SSE3.
La méthode n'est pas nouvelle mais elle s'est révélée contre-productive sur les Pentiums 4. A priori c'est dû à l'architecture du bus de 80 bits (je crois) qui impose de transférer les registres SSE en 2x64bits. Ce qui a des conséquences sur le rythme des calculs dont je te passe les détails (et dont j'en ignore sûrement quelques uns aussi).
Mais l'architecture des Core2Duo est différente, avec des bus internes de 128bits, 2 unités parallèles de calcul SSE + une 3ème unité SSE basique.
Bref je pense pouvoir mieux utiliser le potentiel de ton processeur avec SSE3. De quoi creuser encore l'écart avec ATLAS.
SSE4 d'Intel est décevant.
Je viens de voir qu'AMD prépare SSE5. Y'a beaucoup d'instructions qui me laissent perplexes (en particulier les "mini" nombres à virgule flottante codés sur 16bits). Mais y'aura surtout la possibilité d'utiliser des instructions de multiplication et accumulation, alors qu'il faut actuellement utiliser 2 instructions distinctes. Ca permettra peut-être de multiplier par 2 la vitesse de pas mal de calculs mathématiques.
Hello !!!
je n'ai pas pu faire plus d'investigation...
mais je vais faire un projet xcode maintenant, pour inclure les framework apple... donc je ne sais pas si je pourrais continuer sur gcc 4.2 ...
sur icc au moins !
je le ferais prochainement, mais je n'ai plus une minute a moi ... je suis désolé des réponses tardives ...
je serais très heureux de te tester tes ameliorations et mesurer le speed-up !
re !!!
je pense avoir trouvé comment include carbon !
voici les erreurs:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 /usr/local/bin/g++ main.cpp -o gcc-genial -O2 -I../genial -msse3 -Winline -I/ATLAS/include/ -L/ATLAS/my_build_dir/lib/ -latlas -lcblas -I/ATLAS/my_build_dir/include/ -DNDEBUG -DBLAS_THREADING -DMAX_THREADS=2 -framework Carbon -I/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers In file included from /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Multiprocessing.h:30, from ../genial/threads.h:48, from ../genial/blas/gemm.h:27, from main.cpp:8: /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MacTypes.h:521: error: 'extend' redeclared as different kind of symbol ../genial/array/arraygenerator.h:2798: error: previous declaration of 'template<class G> typename extendArray<const Matrix<G> >::self extend(const Matrix<G>&, const typename Vector::size_type&)' In file included from ../genial/blas/gemm.h:27, from main.cpp:8: ../genial/threads.h: In destructor 'gmt::mutex::~mutex()': ../genial/threads.h:388: error: cannot convert 'OpaqueMPCriticalRegionID**' to 'OpaqueMPCriticalRegionID*' for argument '1' to 'OSStatus MPDeleteCriticalRegion(OpaqueMPCriticalRegionID*)' ../genial/threads.h: In constructor 'gmt::semaphore::semaphore()': ../genial/threads.h:456: error: 'sem_init' was not declared in this scope ../genial/threads.h: In constructor 'gmt::semaphore::semaphore(int)': ../genial/threads.h:457: error: 'sem_init' was not declared in this scope
Merci!
Je pensais pas qu'il te fallait refaire un projet. Mais pourquoi donc?
La doc que j'ai lu sur l'API muti-thread de MacOs conseille un "weak linking", mais je ne sais pas ce que ça veut dire.
C'est pas bien grave pour l'instant comme erreurs.
1) La 1ère erreur est contrariante, parce qu'il y a un conflit de noms. Le nom 'extend' est visiblement également utilisé par Carbon, et donc il va peut-être falloir que je renomme ma fonction. En tout cas, cette fonction n'est pas utilisée dans les modules rendus publics de ma librairie, tu peux sans complexe commenter les 4 déclarations de fonctions dans le fichier 'arraygenerator.h' (ligne 2795 à 2798)
2) Faute d'inattention à la ligne 388 dans 'threads.h', à remplacer par:Code:
1
2
3
4 //template<class G> inline typename extendArray<const Vector<G> >::self extend(const Vector<G> &X) { return extendArray<const Vector<G> >::self(X); } //template<class G> inline typename extendArray<const Matrix<G> >::self extend(const Matrix<G> &X) { return extendArray<const Matrix<G> >::self(X); } //template<class G> inline typename extendArray<const Vector<G> >::self extend(const Vector<G> &X, const typename Vector<G>::size_type &s) { return extendArray<const Vector<G> >::self(X,s); } //template<class G> inline typename extendArray<const Matrix<G> >::self extend(const Matrix<G> &X, const typename Vector<G>::size_type &s) { return extendArray<const Matrix<G> >::self(X,s); }
3)Après un copier-coller, j'ai oublié de renommer la fonction d'initialisation des sémaphores de la librairie pthreads. Il faut remplacer les 2 lignes 456 et 457 de 'threrads.h' parCode:inline ~mutex() { MPDeleteCriticalRegion(mut); }
En espérant qu'il n'y a pas d'autres erreurs de compilation. Et surtout pas d'erreur d'exécution...Code:
1
2 inline semaphore( ) { assert_thread(MPCreateSemaphore(std::numeric_limits<int>::max(),0,&sem)); }; inline semaphore(int n) { assert_thread(MPCreateSemaphore(std::numeric_limits<int>::max(),n,&sem)); };
C'est bon, ca compile et ca tourne !!!
mais pas d'amelioration ! :(
le point vraiment positif c'est que ton encapsulation marche vraiment bien,
et que maintenant peut-etre on pourrait voir le cpu id de chaque thread ?
qu'en penses-tu ?
a+
Je ne sais pas parce que je ne comprends pas pourquoi le multi-threading ne marche pas sur ton mac. Visiblement ce n'est donc pas la faute à pthread. C'est peut-être celle du système...
Qu'est-ce que t'entends par "cpu id" ?
Comment tu comptes faire? Avec un gestionnaire de tâche?
je pense qu'on peut savoir par programmation quel thread sur quel cpu ?
j'aimerais savoir si les threads qu'on utilise se trouve sur le meme cpu ou non, ce qui expliquerait le probleme ...
Il faut bien reconnaître que ça donne l'impression que les threads sont exécutés sur le même cœur.
Je vois franchement pas comment faire pour vérifier ça, à part peut-être un gestionnaire de tâche (bien-sûr son équivalent sous MacOS) pour voir si tous les cœurs sont sollicités. Commente au préalable la mesure d'ATLAS pour éviter de polluer les courbes.
tu pourrais appeler cette fonction
pour chaque thread de créé
on peut donc avoir le lastCPU que j'aimerais bien connaitre pour verifier notre theorie.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 MPExtractTaskState Extracts state information from a suspended task. OSStatus MPExtractTaskState ( MPTaskID task, MPTaskStateKind kind, void * info ); Task State Constants Specify what states you want to set or obtain when calling the MPExtractTaskState or MPSetTaskState functions. enum { kMPTaskStateRegisters = 0, kMPTaskStateFPU = 1, kMPTaskStateVectors = 2, kMPTaskStateMachine = 3, kMPTaskState32BitMemoryException = 4, kMPTaskStateTaskInfo = 5 }; MPTaskInfo Contains information about a task. struct MPTaskInfo { PBVersion version; OSType name; OSType queueName; UInt16 runState; UInt16 lastCPU; UInt32 weight; MPProcessID processID; AbsoluteTime cpuTime; AbsoluteTime schedTime; AbsoluteTime creationTime; ItemCount codePageFaults; ItemCount dataPageFaults; ItemCount preemptions; MPCpuID cpuID; MPOpaqueID blockedObject; MPAddressSpaceID spaceID; LogicalAddress stackBase; LogicalAddress stackLimit; LogicalAddress stackCurr; }; typedef struct MPTaskInfo MPTaskInfo; Fields version The version of this data structure. name The name of the task. queueName A four-byte code indicating the status of the queue waiting on the task. runState The current state of the task (running, ready, or blocked). lastCPU The address of the last processor that ran this task. weight The weighting assigned to this task. processID The ID of the process that owns this task. cpuTime The accumulated CPU time used by the task. schedTime The time when the task was last scheduled. creationTime The time when the task was created. codePageFaults The number of page faults that occurred during code execution. dataPageFaults The number of page faults that occurred during data access. preemptions The number of times this task was preempted. cpuID The ID of the last processor that ran this task. blockedObject spaceID stackBase stackLimit stackCurr Discussion If you specify the kMPTaskStateTaskInfo constant when calling the function MPExtractTaskState , Multiprocessing Services returns state information in an MPTaskInfo structure. Version Notes Introduced with Multiprocessing Services 2.1.
Qu'en penses-tu ?
Essaye dans le destructeur de la class thread pour Mac un truc dans le genre..
Je ne sais pas trop s'il vaut mieux le placer avant ou après la fonction 'join'.
-avant: le thread est normalement en cours d'exécution
-après: le thread est fini
A la fin du benchmark, tu devrais avoir autant de sorties que de threads créés.Code:
1
2
3
4
5
6
7
8
9
10
11
12 inline ~thread() { MPTaskInfo info; MPExtractTaskState(task,kMPTaskStateTaskInfo,&info); cout << "cpuID=" << info.cpuID << endl; join(); MPDeleteQueue(queue); //MPTaskInfo info; //MPExtractTaskState(task,kMPTaskStateTaskInfo,&info); //cout << "cpuID=" << info.cpuID << endl; }
Et voici le benchmark mono-threadé annoncé hier pour Windows, afin de tester un algo spécifiquement conçu pour SSE3, qui s'était révélé décevant sur les Pentium4. J'espère que ça sera différent sur ton Core2Duo.
http://www.ient.rwth-aachen.de/team/...E2_vs_SSE3.zip
Le bench SSE2 sert de référence.
Merci de me poster les 2 fichiers résultants.
Si c'est concluant, j'étendrai la méthode aux matrices complexes.
bon bah on avait raison !!! (mince)
mais il y a un truc de bizarre,Code:
1
2
3 taskid=0x1803600 cpuID=0xbffff90c taskid=0x1803200 cpuID=0xbffff90c
dans le "Activity monitor" je vois les deux cores qui sont chargés pendant l'execution .... je comprend plus rien, serait-ce la faute au system ?
Je suis à court d'idées et je trouve tout ça bizarre aussi.
Je dois reconnaître que ça semble incriminer le système.
Sinon t'as vu le nouveau bench de mon message précédent?