c - 适用于 ARM Mac M1/M2 的 __rdtsc/__rdtscp?

标签 c assembly apple-m1 arm64 microbenchmark

我想在我的代码中插入一些时间测量。在 x64 上我使用 __rdtscp。 mac m1/m2 有类似的东西吗?具体来说,不是系统调用和高分辨率。

最佳答案

只需使用clock_gettime(CLOCK_MONOTONIC,...)

这是一个VDSO函数。这意味着内核将代码注入(inject)到“做正确的事情”的用户空间程序中,因此用户空间程序可以访问时间戳计数器而无需执行系统调用。 p>

在 x86 上,它[通常]会调用 rdtsc [或 PET],并调整计数器值以表示纳秒。

在arm上,TSC是一个控制寄存器,只能在内核模式下访问。但是,高端臂架构允许将其映射为用户空间的 R/O 访问。内核启用映射。然后,VDSO 代码段将知道如何通过映射访问这些值。

clock_gettime 的调用很快。速度如此之快,以至于不值得尝试直接访问计数器寄存器。

此外,直接访问计数器也没有多大意义,因为我们仍然需要将其转换为某种标准单位(例如纳秒)。 VDSO 代码片段将执行此操作。


更新:

Is it a VDSO call on macOS, too? –  fuz

我的直接经验是在 nVidia Jetson [Linux 下] 上使用 ARM。

但是,据我所知,macOS 提供了[必须提供]clock_gettime

在较旧的内核上,它可能必须发出等效的系统调用。

但是,由于架构提供了用户空间直接访问给定操作系统/内核的方法,因此有充分的理由相信 VDSO 方法在 macOS 下也可用。事实上,确实如此:https://www.unix.com/man-page/osx/7/vdso/

查看具体机制的方法是构建一个使用clock_gettime 和[使用gdb]单步执行的程序。然后,可以让gdb反汇编clock_gettime代码。

我们必须使用gdb [与。 objdump 和/或 readelf] 用于反汇编,因为该代码片段是由内核动态加载/注入(inject)的,因此通过静态分析不容易访问它。

此外,注入(inject)的代码可以是特定于处理器模型的。内核在引导期间探测 CPU 架构及其功能。它根据找到的功能制作代码片段。

使用gdb是我检查clock_gettime[大约3年前的商业产品]的方式,以验证它是否可以访问硬件而无需 一个系统调用,并且它提供了正确的纳秒值。在这种特殊情况下,我还查看了内核源代码中的架构特定部分。

关于c - 适用于 ARM Mac M1/M2 的 __rdtsc/__rdtscp?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74757124/

相关文章:

c - 从模数和指数加载 rsa key ,加密字符串,然后进行核心转储

c - 在 C 中使用 x86 风格的跳转表

react-native - react native : how to run flipper with apple silicon

javascript - MAC M1 安装 "sharp"模块出现问题

c - C 中的方法和结构

c - 嵌入式开发的 Pin Mask 约定

c++ - 使用内联 ASM c++ 显示 640x480 BMP 图像

electron-builder - 如何在 M1 Mac 上构建适用于 ARM64 架构的 Quasar 应用程序

c - 在C中插入到队列的末尾

assembly - 常规使用 r10 和 r11 的可接受性