7

我正在尝试使用 linux 上的 WBINV 指令来清除处理器的 L1 缓存。

以下程序可以编译,但是当我尝试运行它时会产生分段错误。

int main() {asm ("wbinvd"); return 1;}

我正在使用 gcc 4.4.3 并在我的 x86 机器上运行 Linux 内核 2.6.32-33。

处理器信息:Intel(R) Core(TM)2 Duo CPU T5270 @ 1.40GHz

我构建的程序如下:

$ gcc

$ ./a.out

分段故障

有人可以告诉我我做错了什么吗?我如何让它运行?

PS:我正在运行一些性能测试,并希望确保处理器缓存的先前内容不会影响结果。

4

2 回答 2

13

引用英特尔® 64 和 IA-32 架构软件开发人员手册合并卷 2A 和 2B:指令集参考,AZ

WBINVD 指令是特权指令。当处理器在保护模式下运行时,程序或过程的 CPL 必须为 0 才能执行该指令。

换句话说,只允许内核模式代码执行它。

编辑:先前关于清除缓存的讨论:

“C”以编程方式清除 Linux 机器上的二级缓存

如何在 x86 Windows 中进行 CPU 缓存刷新?

如何清除 CPU L1 和 L2 缓存

https://stackoverflow.com/questions/3443130/how-to-clear-cpu-l1-and-l2-cache

于 2011-07-19T10:27:16.627 回答
7

正如 user786653 所写,wbinvd这是一条特权指令,在非内核代码中会出现段错误。

您应该避免使用wbinvd基准测试,因为它会强制所有类型的总线锁定周期、管道序列化并增加从内核到用户空间的开销等,这在您的实际程序中很可能不会发生。

因此,您的测量不会更精确,它将包含各种伪像。读取 L2 缓存大小的数据块会产生更好的结果。

您可以阅读测试程序下的源代码以测量时钟周期和性能监控,以了解其他人如何获得有用的结果。

于 2011-07-19T12:31:09.247 回答