6个版本

1.0.0-alpha.62024年8月10日
1.0.0-alpha.52024年6月20日
1.0.0-alpha.42024年5月29日
1.0.0-alpha.32024年2月23日
1.0.0-alpha.12023年12月26日

#39 in 并发

Download history 196/week @ 2024-05-03 285/week @ 2024-05-10 332/week @ 2024-05-17 675/week @ 2024-05-24 388/week @ 2024-05-31 323/week @ 2024-06-07 475/week @ 2024-06-14 627/week @ 2024-06-21 305/week @ 2024-06-28 340/week @ 2024-07-05 285/week @ 2024-07-12 467/week @ 2024-07-19 525/week @ 2024-07-26 460/week @ 2024-08-02 604/week @ 2024-08-09 325/week @ 2024-08-16

1,986 每月下载量
10 个Crate中使用(直接使用5个)

MIT 许可证

1.5MB
24K SLoC

hwlocality:hwloc库的Rust绑定

MIT licensed Package on crates.io Documentation Continuous Integration Code coverage CII Best Practices Summary Requires rustc 1.75.0+

这是什么?

为了优化程序在所有硬件上的并行性能,你必须承认,在许多常见的平台上,操作系统中检测到的“CPU”通常对共享资源(如缓存、DRAM和I/O外围设备)的访问是不平等的,有时甚至规格也不一致(如Arm big.LITTLE、Apple Mx和Intel Adler Lake),通过在代码中考虑这些事实,可以获得显著的性能提升。

这是对Open MPI的C库hwloc的最新维护Rust绑定,hwloc用于检测现代架构的层次拓扑:NUMA内存节点、插座、共享数据与指令缓存、核心、同时多线程等。此外,hwloc允许您将线程固定到特定的CPU核心,并将内存固定到特定的NUMA节点,这是进行拓扑感知程序优化的先决条件。

hwlocality基于之前已不再维护的Rust hwloc绑定尝试,并与Ichbinjoe/hwloc2-rsdaschl/hwloc-rs共享一些代码和设计。然而,它并不追求与它们的API兼容性。实际上,在改善易用性、性能以及消除诸如假定指针非空或联合字段有效(当没有人告诉你它们始终有效时)之类的未定义行为方面,已经对hwloc2-rs进行了许多更改。

先决条件

hwlocalitylibhwloc v2.0及以后版本兼容。您可以通过两种不同的方式安装合适的libhwloc版本:

  1. 如果您的包管理器提供了相对较新的 libhwloc 包,那么您可以同时安装它以及相关的开发包(通常称为 libhwloc-devlibhwloc-devel)。这是推荐的安装方式,因为它将大大加快您的 hwlocality(重新)构建速度,并允许您轻松地与开发环境中的其他部分一起更新 libhwloc
  2. 如果由于任何原因您无法使用上述方法,那么 hwlocality 可以选择下载并构建自己的 libhwloc 版本。要使用这种内部构建,请启用 vendored Cargo 功能。除了正常工作的 C 构建环境外,在类 Unix 系统上您还需要 automakelibtool,而在 Windows 上则需要 cmake

除非您使用的是 Windows 的 vendored 版本 hwloc,否则您还需要安装 pkg-config 或其克隆版本之一(如 pkgconfpkgconfiglite 等),因为它用于查找 libhwloc 并设置 hwlocality 以链接到它。

默认情况下,目标是兼容所有 hwloc 2.x 版本,这意味着 2.x 系列中新版本的功能(或者在不久的将来,与 3.x 系列的破坏性更改的兼容性)默认情况下不支持。

您可以通过启用与您需要兼容的最低 hwloc 版本匹配的 cargo 功能来启用它们,这将以失去与较旧 hwloc 2.x 版本的兼容性为代价。有关更多信息,请参阅此 crate 的 Cargo.toml 的 [features] 部分

用法

首先,将 hwlocality 添加为依赖项

cargo add hwlocality

然后,在您的代码内部设置一个 Topology。这是进入 hwloc 库的主要入口点,通过它可以访问几乎所有的 hwloc 允许的操作。

以下是一个快速使用示例,它遍历检测到的硬件拓扑并打印出 hwloc 所知每个 CPU 和缓存对象的简短描述

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(())
}

一个可能的输出是

*** 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

更多示例可以在 源代码存储库中找到

hwloc API 覆盖率

现在,hwlocality 揭示了 hwloc 2.x 系列中的大多数功能。但由于各种原因,一些专用功能,主要与与其他 API 的互操作性相关,无法实现。标记为 "api coverage" 的问题跟踪未实现的功能,如果您有时间,这是一个寻找对该库潜在贡献的好地方!

如果您已经熟悉 hwloc C API,您还将很高兴地知道,广泛使用了 #[doc(alias)] 属性,这样您就可以在文档中搜索 hwloc API 实体,如 hwloc_bitmap_thwloc_set_cpubindhwloc_obj::arity,并将重定向到 Rust API 中建议的替代品。

此规则的主要例外是由于Rust类型系统允许的语法改进,使得某些概念在Rust中不需要。例如...

  • C风格的手动析构函数被Drop实现所取代
  • HWLOC_MEMBIND_BYNODESET之类的类型参数澄清标志被自动执行正确操作的泛型所取代。

许可协议

本项目使用MIT许可协议,请参阅LICENSE文件以获取更多信息。

依赖项

~0.6–10MB
~104K SLoC