6个版本
1.0.0-alpha.6 | 2024年8月10日 |
---|---|
1.0.0-alpha.5 | 2024年6月20日 |
1.0.0-alpha.4 | 2024年5月29日 |
1.0.0-alpha.3 | 2024年2月23日 |
1.0.0-alpha.1 | 2023年12月26日 |
#39 in 并发
1,986 每月下载量
在 10 个Crate中使用(直接使用5个)
1.5MB
24K SLoC
hwlocality:hwloc库的Rust绑定
这是什么?
为了优化程序在所有硬件上的并行性能,你必须承认,在许多常见的平台上,操作系统中检测到的“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-rs和daschl/hwloc-rs共享一些代码和设计。然而,它并不追求与它们的API兼容性。实际上,在改善易用性、性能以及消除诸如假定指针非空或联合字段有效(当没有人告诉你它们始终有效时)之类的未定义行为方面,已经对hwloc2-rs进行了许多更改。
先决条件
hwlocality
与libhwloc
v2.0及以后版本兼容。您可以通过两种不同的方式安装合适的libhwloc
版本:
- 如果您的包管理器提供了相对较新的
libhwloc
包,那么您可以同时安装它以及相关的开发包(通常称为libhwloc-dev
或libhwloc-devel
)。这是推荐的安装方式,因为它将大大加快您的hwlocality
(重新)构建速度,并允许您轻松地与开发环境中的其他部分一起更新libhwloc
。 - 如果由于任何原因您无法使用上述方法,那么
hwlocality
可以选择下载并构建自己的libhwloc
版本。要使用这种内部构建,请启用vendored
Cargo 功能。除了正常工作的 C 构建环境外,在类 Unix 系统上您还需要automake
和libtool
,而在 Windows 上则需要cmake
。
除非您使用的是 Windows 的 vendored 版本 hwloc,否则您还需要安装 pkg-config
或其克隆版本之一(如 pkgconf
、pkgconfiglite
等),因为它用于查找 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_t
、hwloc_set_cpubind
或 hwloc_obj::arity
,并将重定向到 Rust API 中建议的替代品。
此规则的主要例外是由于Rust类型系统允许的语法改进,使得某些概念在Rust中不需要。例如...
- C风格的手动析构函数被
Drop
实现所取代 - 如
HWLOC_MEMBIND_BYNODESET
之类的类型参数澄清标志被自动执行正确操作的泛型所取代。
许可协议
本项目使用MIT许可协议,请参阅LICENSE文件以获取更多信息。
依赖项
~0.6–10MB
~104K SLoC