Pour optimiser les programmes de performances parallèles sur tout le matériel, vous devez accepter que sur de nombreuses plates-formes communes, le multiprocessement symétrique est un mensonge. Les "CPU" détectés par le système d'exploitation ont souvent un accès inégal à des ressources partagées comme les caches, les périphériques DRAM et E / S, parfois même des spécifications inégales (comme dans le bras ARM Big.Little, Apple MX et Intel Adler Lake), et des gains de performances significatifs peuvent être obtenus en prenant ces faits en compte dans votre code.
Il s'agit de la dernière liaison de la rouille maintenue à HWLOC, une bibliothèque C d'Open MPI pour détecter la topologie hiérarchique des architectures modernes: nœuds de mémoire NUMA, prises, caches de données et d'instructions partagées, noyaux, multic simultanés, et plus encore. De plus, HWLOC vous permet d'épingler des threads à des cœurs CPU et à une mémoire spécifiques à des nœuds NUMA spécifiques, ce qui est une condition préalable pour effectuer des optimisations de programme de topologie.
hwlocality est basé sur et partage toujours du code et de la conception avec les tentatives précédentes, désormais insuffisantes d'écrire des liaisons Rust Hwloc sur Ichbinjoe / Hwloc2-RS et Daschl / Hwloc-RS. Cependant, il ne vise pas la compatibilité des API avec eux. En effet, de nombreux changements ont été apportés en ce qui concerne les HWLOC2-RS dans le but d'améliorer l'ergonomie, la performance et la suppression des voies pour un comportement non défini, comme supposer que les pointeurs sont des domaines non nuls ou syndicaux sont valides lorsque personne ne vous dit qu'il le sera toujours.
hwlocality est compatible avec libhwloc v2.0 et plus tard. Vous pouvez installer une version appropriée de libhwloc de deux manières différentes:
libhwloc raisonnablement récent, vous pouvez l'installer avec le package de développement associé (généralement appelé libhwloc-dev ou libhwloc-devel ). C'est la façon recommandée de faire les choses, car elle accélérera considérablement votre hwlocality (RE) construit et vous permettra de garder à jour libhwloc facilement avec le reste de votre environnement de développement.hwlocality peut alternativement télécharger et créer sa propre copie de libhwloc . Pour utiliser une telle version interne, veuillez activer la fonction de cargaison vendored . En plus d'un environnement de construction C de travail, vous aurez besoin automake et libtool sur les unices et cmake sur Windows. À moins que vous n'utilisiez une version vendue de HWLOC de Windows, vous devrez également installer pkg-config ou l'un de ses clones ( pkgconf , pkgconfiglite ...), comme il est utilisé pour trouver libhwloc et configurer hwlocality pour lui lier.
Par défaut, la compatibilité avec toutes les versions HWLOC 2.x s'adresse, ce qui signifie que les fonctionnalités des versions plus récentes de la série 2.x (ou, dans un avenir proche, la compatibilité avec les changements de rupture de la série 3.x) ne sont pas pris en charge par défaut.
Vous pouvez leur permettre, au prix de perdre la compatibilité avec les versions HWLOC 2.x plus anciennes, en permettant à la fonction de fret qui correspond à la version HWLOC la plus basse avec laquelle vous devez être compatible. Voir la section [features] de la cargaison de cette caisse.toml pour plus d'informations.
Tout d'abord, ajoutez hwlocality comme dépendance:
cargo add hwlocality Ensuite, à l'intérieur de votre code, configurez une Topology . Il s'agit du point d'entrée principal de la bibliothèque HWLOC, à travers laquelle vous pouvez accéder à presque toutes les opérations que Hwloc permet.
Voici un exemple d'utilisation rapide qui marche dans la topologie matérielle détectée et imprime une brève description de chaque processeur et objet de cache connu de HWLOC:
use hwlocality :: { object :: depth :: NormalDepth , Topology } ;
fn main ( ) -> eyre :: Result < ( ) > {
let topology = Topology :: new ( ) ? ;
for depth in NormalDepth :: iter_range ( NormalDepth :: MIN , topology . depth ( ) ) {
println ! ( "*** Objects at depth {depth}" ) ;
for ( idx , object ) in topology . objects_at_depth ( depth ) . enumerate ( ) {
println ! ( "{idx}: {object}" ) ;
}
}
Ok ( ( ) )
}Une sortie possible est:
*** Objects at depth 0
0: Machine
*** Objects at depth 1
0: Package
*** Objects at depth 2
0: L3 (16MB)
*** Objects at depth 3
0: L2 (512KB)
1: L2 (512KB)
2: L2 (512KB)
3: L2 (512KB)
4: L2 (512KB)
5: L2 (512KB)
*** Objects at depth 4
0: L1d (32KB)
1: L1d (32KB)
2: L1d (32KB)
3: L1d (32KB)
4: L1d (32KB)
5: L1d (32KB)
*** Objects at depth 5
0: Core
1: Core
2: Core
3: Core
4: Core
5: Core
*** Objects at depth 6
0: PU
1: PU
2: PU
3: PU
4: PU
5: PU
6: PU
7: PU
8: PU
9: PU
10: PU
11: PU
Plus d'exemples sont disponibles dans le référentiel source.
La plupart des fonctionnalités de la série HWLOC 2.x sont désormais exposées par Hwlocality. Mais certaines fonctionnalités spécialisées, principalement liées à l'interopérabilité avec d'autres API, n'ont pas pu le faire pour diverses raisons. Problèmes avec l'étiquette "API Coverage" Trace les fonctionnalités non implémentées, et sont un excellent endroit pour rechercher des contributions potentielles à cette bibliothèque si vous avez le temps!
Si vous connaissez déjà l'API HWLOC C, vous serez également heureux de savoir que les attributs #[doc(alias)] sont largement utilisés afin que vous puissiez rechercher la documentation des entités API HWLOC comme hwloc_bitmap_t , hwloc_set_cpubind ou hwloc_obj::arity et être redirigé à la remplacement suggéré suggéré dans le Rust API.
Les principales exceptions à cette règle sont les notions qui ne sont pas nécessaires dans la rouille en raison des améliorations de l'ergonomie autorisées par le système de type rouille. Par exemple...
Drop implosHWLOC_MEMBIND_BYNODESET sont remplacés par des génériques qui font automatiquement la bonne chose. Ce projet utilise la licence MIT, veuillez consulter le fichier de licence pour plus d'informations.