Comment s’assurer que std :: thread est créé dans multi core?

J’utilise Visual Studio 2012. J’ai un module dans lequel je dois lire un grand nombre de fichiers à partir du disque dur après avoir parcouru les chemins correspondants dans un fichier xml. Pour cela je fais

std::vector m_ThreadList; 

Dans une boucle de temps, je repousse un nouveau fil dans ce vecteur, quelque chose comme

 m_ThreadList.push_back(std::thread(&MyClass::Readfile, &MyClassObject, filepath,std::ref(polygon))); 

Ma connaissance du multi-threading C ++ 11 est limitée. La question que je me pose est de savoir comment créer un thread sur un kernel spécifique. Je connais parallel_for et parallel_for_each dans vs2012, qui optimisent l’utilisation des cœurs. Mais existe-t-il un moyen de faire cela en utilisant la norme C ++ 11?

Comme indiqué dans d’autres commentaires, vous ne pouvez pas créer de fil “sur un kernel spécifique”, car C ++ n’a pas connaissance de ces détails architecturaux. De plus, dans la majorité des cas, le système d’exploitation sera capable de gérer assez bien la dissortingbution des threads entre les cœurs / processeurs.

Cela dit, il existe des cas dans lesquels forcer une dissortingbution spécifique de threads entre les cœurs peut être bénéfique pour les performances. Par exemple, en forçant un thread à s’exécuter sur un kernel spécifique, il peut être possible de minimiser le transfert de données entre différents caches de processeur (ce qui peut être critique pour les performances dans certains scénarios liés à la mémoire).

Si vous souhaitez suivre cette voie, vous devrez vous pencher sur des routines spécifiques à la plate-forme. Par exemple, pour GNU / linux avec des threads POSIX, vous voudrez pthread_setaffinity_np() , dans FreeBSD cpuset_setaffinity() , dans Windows SetThreadAffinityMask() , etc.

J’ai quelques extraits de code pertinents ici si vous êtes intéressé:

http://gitorious.org/piranhapp0x/mainline/blobs/master/src/thread_management.cpp

Je suis assez certain que l’affinité principale n’est pas incluse dans std :: thread. L’hypothèse est que le système d’exploitation est parfaitement capable de tirer le meilleur parti possible des cœurs disponibles. Dans tous les cas, sauf le plus extrême des cas, vous n’allez pas battre la décision de l’OS, l’hypothèse est donc juste.

Si vous vous engagez dans cette voie, vous devrez append un élément décisionnel à votre code pour tenir compte de l’architecture de la machine afin de vous assurer que votre décision est meilleure que celle du système d’exploitation de chaque machine sur laquelle vous exécutez. Cela prend beaucoup d’effort! Pour commencer, vous voudrez limiter le nombre de threads afin qu’il corresponde au nombre de cœurs de l’ordinateur. Et vous ne savez pas ce qui se passe dans la machine; l’OS fait!

C’est pourquoi les pools de threads existent. Ils ont tendance par défaut à avoir autant de threads qu’il y a de cœurs, automatiquement configurés par le runtime de la langue. Autant que je sache, C ++ 11 n’en a pas. La meilleure chose à faire pour optimiser les performances est donc de connaître le nombre de cœurs et de limiter le nombre de threads à ce nombre. Sinon, il vaut probablement mieux faire confiance au système d’exploitation.

Le commentaire de Joachim Pileborg mérite que l’on s’y attarde, à moins que le travail effectué par chaque thread ne soit supérieur aux frais généraux d’E / S.

Voici un aperçu rapide du threading dans le contexte de la dissortingbution de threads vers des cœurs:

La plupart des systèmes d’exploitation modernes utilisent des threads de niveau kernel, ou hybrides. Avec les threads au niveau du kernel, le système d’exploitation “voit” tous les threads de chaque processus; contrairement aux threads de niveau utilisateur, qui sont utilisés en Java, où le système d’exploitation ne voit qu’un seul processus et n’a aucune connaissance du threading. Maintenant, étant donné que, avec le threading au niveau du kernel, le système d’exploitation peut reconnaître les threads distincts d’un processus et gérer leur envoi sur un core donné, il existe un potentiel de parallélisme réel, dans lequel plusieurs threads du même processus sont exécutés sur des cœurs différents. En tant que programmeur, vous n’aurez aucun contrôle sur cela lorsque vous utiliserez std::thread ; l’OS décide. Avec le threading au niveau utilisateur, toute la gestion des threads se fait au niveau utilisateur, avec Java, une bibliothèque gère la “répartition”. Dans le cas du threading hybride, le threading du kernel est utilisé, chaque thread du kernel étant en fait un ensemble de threads de niveau utilisateur.