Linux 的清 CPU cache 的函数是哪个?

2023-09-05 22:11:43 +08:00
 amiwrong123

目前我正在 linux 上,写一个用户态的一个 c 程序。里面有一个逻辑是,去写了一段 RAM ,但写的动作实际上只发生在了 x86 CPU 的 cache 里面,还没有真正写到 RAM 里,然后这导致了错误发生(可以认为我需要结合 DMA 做一些操作,但 DMA 需要读到的东西还在 CPU 的 cache 里面呢)。

所以我想知道,linux 里有提供这种函数吗?(类似 arm ,都会提供这种函数的)

另外,我在网上搜,搜到的 全是 shell 里执行的命令:sync; echo 1 > /proc/sys/vm/drop_caches。这个关键词到底该怎么搜索。

2342 次点击
所在节点    程序员
33 条回复
Yourshell
2023-09-05 22:15:53 +08:00
你用 C 也可以写/proc/sys/vm/drop_caches 啊
Yourshell
2023-09-05 22:16:43 +08:00
Linux 文件就是接口
geelaw
2023-09-05 22:17:24 +08:00
关键词是 linux flush cpu cache
Yourshell
2023-09-05 22:17:53 +08:00
codehz
2023-09-05 22:21:58 +08:00
我觉得这里有很多概念上的问题啊。。。
/proc/sys/vm/drop_caches 这个显然和 cpu cache 没有关系
你要 bypass cpu cache 的话,直接 volatile 不就好了
amiwrong123
2023-09-05 22:26:13 +08:00
@codehz
指针加 volatile 应该也可以 达到我的目的,但可能效率会变低。

所以还是想用 清 cache 的函数。
leonshaw
2023-09-05 22:28:36 +08:00
XY 问题
ljn917
2023-09-05 22:31:34 +08:00
感觉 memory order/fence 可以,但是需要 C11

https://en.cppreference.com/w/c/atomic/memory_order
codehz
2023-09-05 22:31:51 +08:00
@amiwrong123 (小寄巧:用 *(volatile int __attribute__((force)) *)&x = 1 写入
内核也在用,不过把 __attribute__((force)) 加了个宏__force 简化)
geelaw
2023-09-05 22:32:44 +08:00
读了一下文档,看起来 drop_caches 只能清除文件系统里没有写过的缓存,sync 的作用是刷新所有文件,此外楼主的命令的影响范围是整个系统,而不是自己的进程,这样做几乎永远是错误的。

@codehz #5 可能楼主需要写很多内容后一起刷新?
codehz
2023-09-05 22:34:26 +08:00
不过 linux 用内核用是有正当理由的,你这是 x86 带有硬件 dma 或者别的硬件内存映射技术一类的吗,那样用户态也访问不到吧
codehz
2023-09-05 22:35:54 +08:00
@geelaw 我感觉根本不是一个目的啊,drop_caches drop 的是 page cache 这些,和 cpu 缓存一点关系都没,下文提及的也看出不太像是访问文件的问题)
amiwrong123
2023-09-05 22:37:51 +08:00
@codehz
是的,用到了硬件的 DMA 。
用户态是可以访问的呀,只要最终映射出一个虚拟地址出来给 CPU 用就好了。我的程序逻辑很简单,以 RAM 作为交互,简单来说,CPU 先往 RAM (也就是内存条)里写,然后 DMA 从 RAM 里读。
sujin190
2023-09-05 22:40:07 +08:00
没听说过还有手动清 cpu cache line 的,并发不一致也仅限于多核并发写,cpu 都自己管理好了和内存一致,时钟周期级别的一致,否则那么多程序都只是 lock 一下就能从内存读到正确值岂不是都要挂了,如果你硬要说有那应该就是 lock 之类的操作触发总线同步来标记 cache line 无效就是了吧
shimanooo
2023-09-05 22:43:00 +08:00
volatile?
polaa
2023-09-05 22:43:32 +08:00
缓存一致性问题 关键词 Cache coherence

函数 : __clear_cache

指令 clflash wbinvd
codehz
2023-09-05 22:45:46 +08:00
@amiwrong123 参考这个 https://github.com/ikwzm/udmabuf mmap 的时候加一个 O_SYNC
codehz
2023-09-05 22:52:59 +08:00
虽然理论上这种情况还有编译器优化的问题,也就是如果 a b a 这样写,可能会跳过中间的 b
再用前面说的 volatile 转换方式也不迟(
codehz
2023-09-05 22:56:13 +08:00
哦,不对,编译器优化用 asm volatile("" ::: "memory");隔开就够了,O_SYNC 配合合适的用户态 dma 映射实现,应该就足够了
(不过用户态 dma 你还是得考虑调度的问题,没准你循环写入的时候进程被调度走了呢)
polaa
2023-09-05 22:57:09 +08:00
然后你的这种做法的关键词是 self-modifying code ,但是我只接触过 arm 架构的 x86 架构不熟悉

可以参考一下 intel 的 Intel® 64 and IA-32 Architectures Optimization Reference Manual
@polaa

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/971217

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX