Comment forcer deux processus à s’exécuter sur le même processeur?

Le contexte:

Je programme un système logiciel composé de plusieurs processus. Il est programmé en C ++ sous Linux. et ils communiquent entre eux en utilisant la mémoire partagée Linux.

Habituellement, dans le développement logiciel, la dernière étape est l’optimisation des performances. Ici je suis venu à un gros problème. Le logiciel requirejs des performances élevées, mais dans les machines à 4 ou 8 cœurs de processeur (généralement avec plus d’un processeur), il n’a pu utiliser que 3 cœurs, gaspillant ainsi 25% de la puissance du processeur dans les premiers et plus de 60% dans les deuxièmes. Après de nombreuses recherches et après avoir écarté les conflits mutex et verrous, j’ai découvert que le temps était gaspillé en appels shmdt / shmat (détacher et joindre à des segments de mémoire partagée). Après quelques recherches supplémentaires, j’ai découvert que ces processeurs, généralement AMD Opteron et Intel Xeon, utilisent un système de mémoire appelé NUMA, ce qui signifie que chaque processeur dispose de sa “mémoire locale” rapide et que l’access à la mémoire à partir d’autres processeurs est coûteux.

Après avoir effectué quelques tests, le problème semble être que le logiciel est conçu pour que, de manière générale, tout processus puisse transmettre des segments de mémoire partagée à tout autre processus et à l’un de leurs threads. Cela semble nuire aux performances, car les processus accèdent constamment à la mémoire d’autres processus.

Question:

Maintenant, la question est de savoir s’il existe un moyen de forcer des paires de processus à s’exécuter dans le même processeur? Je ne veux pas les forcer à exécuter toujours dans le même processeur, peu importe le type d’exécution, même si cela ferait l’affaire. Idéalement, il y aurait un moyen de dire au kernel: si vous planifiez ce processus dans un processeur, vous devez également planifier ce processus “frère” (qui est le processus avec lequel il communique via la mémoire partagée) dans ce même processeur, de sorte que la performance n’est pas pénalisée.

    Je pense que vous pourrez peut-être commencer par ces pages de manuel:

    $ apropos affinity sched_getaffinity (2) - set and get a process's CPU affinity mask sched_setaffinity (2) - set and get a process's CPU affinity mask taskset (1) - resortingeve or set a process's CPU affinity $ 

    selon que vous voulez le faire à partir du code source ou du shell. La bibliothèque pthread a également une fonction.

    En C, vous recherchez probablement l’appel système sched_setaffinity() .

    Il existe également l’utilitaire de ligne de commande schedtool si vous ne souhaitez pas (ou ne pouvez pas) modifier votre code.

    L’écriture d’applications NUMA est un peu plus que «deux processus exécutés sur le même processeur». La conscience NUMA imprègne tout: allocation de mémoire, achèvement d’IO, planification de threads, etc.

    Regarde libnuma