Para optimizar los programas para el rendimiento paralelo en todo el hardware, debe aceptar que en muchas plataformas comunes, el multiprocesamiento simétrico es una mentira. Las "CPU" detectadas por el sistema operativo a menudo tienen un acceso desigual a recursos compartidos como cachés, DRAM y periféricos de E/S, a veces incluso especificaciones desiguales (como en el brazo grande. Little, Apple MX e Intel Adler Lake), y se pueden lograr ganancias de rendimiento significativas teniendo en cuenta estos hechos en su código.
Esta es la última unión de óxido mantenida a HWLOC, una biblioteca C de MPI abierta para detectar la topología jerárquica de las arquitecturas modernas: nodos de memoria NUMA, enchufes, cachés de datos e instrucciones compartidos, núcleos, hilo múltiple simultáneo y más. Además, HWLOC le permite pinchar hilos a núcleos de CPU específicos a nodos NUMA específicos, que es un requisito previo para realizar optimizaciones del programa consciente de la topología.
hwlocality se basa y aún comparte algún código y diseño con los intentos anteriores, ahora sin mantenimiento de escribir enlaces de HWLOC de óxido en Ichbinjoe/HWLOC2-RS y DASCHL/HWLOC-RS. Sin embargo, no apunta a la compatibilidad de la API con ellos. De hecho, se han realizado muchos cambios con respecto a HWLOC2-RS en el objetivo de mejorar la ergonomía, el rendimiento y eliminar las vías para el comportamiento indefinido, como asumir que los consejos no son válidos o los campos sindicales son válidos cuando nadie le dice que siempre lo serán.
hwlocality es compatible con libhwloc v2.0 y posterior. Puede instalar una versión adecuada de libhwloc de dos maneras diferentes:
libhwloc razonablemente reciente, puede instalarlo junto con el paquete de desarrollo asociado (generalmente llamado libhwloc-dev o libhwloc-devel ). Esta es la forma recomendada de hacer las cosas porque acelerará en gran medida sus construcciones hwlocality (re) y le permitirá mantener fácilmente libhwloc actualizado junto con el resto de su entorno de desarrollo.hwlocality puede descargar y construir su propia copia de libhwloc . Para utilizar una construcción de este tipo, habilite la función de carga vendored . Además de un entorno de construcción de C Working, necesitará automake y libtool en Unices, y cmake en Windows. A menos que esté utilizando una versión proveida de HWLOC de Windows, también deberá instalar pkg-config o uno de sus clones ( pkgconf , pkgconfiglite ...), ya que se usa para encontrar libhwloc y configurar hwlocality para vincularlo.
De manera predeterminada, está dirigida a la compatibilidad con todas las versiones HWLOC 2.x, lo que significa que las características de las versiones más nuevas en la serie 2.x (o, en el futuro cercano, la compatibilidad con los cambios de ruptura de la serie 3.x) no son compatibles de forma predeterminada.
Puede habilitarlos, a costa de perder la compatibilidad con las versiones más antiguas de HWLOC 2.x, habilitando la función de carga que coincida con la versión HWLOC más baja con la que necesita ser compatible. Consulte la sección [features] de la carga de esta caja.toml para obtener más información.
Primero, agregue hwlocality como dependencia:
cargo add hwlocality Luego, dentro de su código, configure una Topology . Este es el principal punto de entrada a la biblioteca HWLOC, a través del cual puede acceder a casi todas las operaciones que permiten HWLOC.
Aquí hay un ejemplo de uso rápido que camina a través de la topología de hardware detectada e imprime una breve descripción de cada CPU y objeto de caché conocido por 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 ( ( ) )
}Una posible salida es:
*** 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
Hay más ejemplos disponibles en el repositorio de origen.
La mayoría de las características de la serie HWLOC 2.x ahora están expuestas por HWLocality. Pero algunas características especializadas, principalmente relacionadas con la interoperabilidad con otras API, no podrían hacerlo por varias razones. ¡Problemas con las características no implementadas de la etiqueta de "cobertura API", y son un excelente lugar para buscar contribuciones potenciales a esta biblioteca si tiene tiempo!
Si ya está familiarizado con la API HWLOC C, también estará encantado de saber que los atributos #[doc(alias)] se usan ampliamente para que pueda buscar la documentación para entidades de API HWLOC como hwloc_bitmap_t , hwloc_set_cpubind o hwloc_obj::arity y se redirige a la reemplazo sugerido en el api rani -api.
Las principales excepciones a esta regla son las nociones que no son necesarias en el óxido debido a las mejoras ergonómicas permitidas por el sistema de tipos de óxido. Por ejemplo...
DropHWLOC_MEMBIND_BYNODESET son reemplazados por genéricos que hacen lo correcto automáticamente. Este proyecto utiliza la licencia MIT, consulte el archivo de licencia para obtener más información.