La règle générale pour les threads est que vous voulez au moins un thread de travail "actif" (capable d'exécuter ses commandes immédiatement en fonction du temps CPU) pour chaque "unité d'exécution" disponible sur l'ordinateur. Une «unité d'exécution» est un processeur d'instructions logiques, donc un serveur hyperthreadé Xeon quadruple puce quadruple cœur aurait 32 EU (4 puces, 4 cœurs par puce, chaque hyperthreadé). Votre Core i7 moyen en aurait 8.
Un thread par UE est l'utilisation la plus complète de la puissance du processeur, à condition que les threads soient toujours en état de fonctionnement; ce n'est presque jamais le cas, car les threads doivent avoir accès à la mémoire non mise en cache, au disque dur, aux ports réseau, etc. qu'ils doivent attendre et qui ne nécessitent pas d'attention active du processeur pour fonctionner. Vous pouvez ainsi augmenter encore l'efficacité globale avec plus de threads en file d'attente et prêts à partir. Cela a un coût; lorsqu'un CPU commute un thread, il doit mettre en cache les registres du thread, le pointeur d'exécution et d'autres informations d'état normalement conservés dans le fonctionnement le plus interne d'une UE et accessibles très rapidement, permettant aux autres EU de cette puce de CPU de les récupérer. Il nécessite également des threads dans le système d'exploitation pour décider quel thread doit être basculé. Enfin, lorsqu'une UE change de fil, il perd les gains de performances du pipeline que la plupart des architectures de processeurs utilisent; il doit vider le pipeline avant de changer de threads. Mais, comme tout cela prend encore beaucoup moins de temps en moyenne que d'attendre simplement que le disque dur ou même la RAM revienne avec des informations, cela en vaut le coût.
Cependant, en général, une fois que vous avez dépassé le double du nombre de threads "actifs" en tant qu'UE, le système d'exploitation commence à consacrer plus de temps aux threads de planification de l'UE et les UE passent plus de temps à basculer entre eux que ce qui est réellement passé à exécuter des threads actifs. des programmes. C'est le point des déséconomies d'échelle; il faudra en fait plus de temps pour qu'un algorithme multithread s'exécute si vous deviez ajouter un thread supplémentaire à ce stade.
Donc, dans l'ensemble, vous voulez conserver au moins autant de threads dans votre programme que vous avez d'UE sur l'ordinateur, mais vous voulez éviter d'avoir plus du double de ce nombre qui n'attendent pas ou ne dorment pas.