M1平台sys_icache_invalidate()性能问题及相关技术疑问
我在搭载M1芯片、运行macOS 13.2的MacBook Air上开发、测试并基准测试JIT代码生成方案,所有测试均通过,对比传统无代码生成方案表现尚可。按常规流程,生成代码前需调用pthread_jit_write_protect_np(0)启用可执行页面写入,生成后调用pthread_jit_write_protect_np(1)恢复写保护,随后调用sys_icache_invalidate()解决L1指令缓存与数据缓存的一致性问题。
注释掉sys_icache_invalidate()后,代码执行仅需数百纳秒,和传统方案竞争力很强,甚至优化后有超越的可能,但此时代码无法正常工作;恢复调用该函数后,执行时间增加近3µs,直接导致JIT方案性能远不如传统方案。
查看Apple的sys_icache_invalidate()实现,其逻辑是对每个缓存行执行ic ivau, xN指令(xN存缓存行起始地址),随后执行dsb ish和isb。我尝试过在生成每个缓存行后就执行ic ivau, xN,最后再执行dsb ish和isb,期望能和代码生成并行执行,但代码依然无法正常工作,仅节省了数百纳秒;之后又尝试在每次执行ic ivau, xN前调用pthread_jit_write_protect_np(1),执行后再调用pthread_jit_write_protect_np(0),但发现还是必须调用Apple的sys_icache_invalidate()才能让代码正常运行。
虽已准备放弃该JIT方案,但仍有以下疑问:
ic ivau, xN是否会阻塞M1,即阻止其他指令并行执行或刷新流水线?- 若页面处于可写入状态,
ic ivau, xN是否真的无法生效?或是pthread_jit_write_protect_np()在底层执行了和写保护无关的操作,无需实际开启写保护也能实现缓存失效? - 是否存在其他缓存行失效方案,能降低这部分性能开销?
内容的提问来源于stack exchange,提问作者swineone

