学习一下CYY师兄的工作,part1 https://www.rv64.zip/

Background&Motivation

1.理想的RISC-V板子应当包含一组标准的指令拓展RVA23U64,但是目前的生态下,不同硬件支持的拓展与标准并不一致;

2.编译器和CPU没有针对新拓展进行优化的话,盲目打开新拓展反而会导致程序性能下降

Existing solution

1.target_clones attributes 改代码,维护成本高

间接调用开销:

image-20250707222013694

When using target_clones or target_version, the compiler will use GNU IFUNC to dispatch the function call to the correct version at runtime. This introduces an overhead of an indirect function call, and also refuses some optimizations such as inlining. When compiling without -fno-plt or with -fno-pic, things will be worse since it requires 2 level call to the function (the first level is PLT call).

前置知识:

PLT(Procedure Linkage Table)

PLT 是动态链接(共享库)中用于实现 延迟绑定(Lazy Binding) 的核心结构,解决程序调用共享库函数时的跳转问题。

  1. 首次调用函数时:

    • 程序跳转到 PLT 表中的对应条目(如 printf@plt)。
    • PLT 条目包含一条跳转指令,默认指向 动态链接器(_dl_runtime_resolve)。
    • 动态链接器解析函数真实地址,并回填到 GOT(Global Offset Table)。
  2. 后续调用时:

    • PLT 直接通过 GOT 跳转到真实函数地址(无需再次解析)。

    -fno-plt 选项可绕过 PLT,直接通过 GOT 调用

IFUCN(Indirect Function)

运行时动态选择函数的具体实现,通过函数指针跳转,比直接调用多一次寻址,地址运行时确定,无法内联

定义时通过 __ attribute__((ifunc("resolver")))标记函数,提供一个解析器函数。

1
2
3
4
5
static void* my_func_resolver() {
if (__builtin_cpu_supports("avx2")) return &my_func_avx2;
else return &my_func_default;
}
void my_func() __attribute__((ifunc("my_func_resolver")));

最佳案例:GLib通过IFUNC为memcpy提供了多个实现。

Solution

1.Decoupled function clone table

​ 相当于将target_clones attributes从函数层提升到了文件层,不需要修改源代码。patch

2.Automatic function clone table generation

​ 根据perf结果选择最佳的result

3.针对直接调用提了一些编译器端和CPU端的支持

image-20250707224604165

期待CYY师兄的正式论文,后续继续学习

Other

1.英语表达读起来好舒服

2.类似的方案在box64之类的二进制翻译场景下也大有用处。


本站由 Zane Jiang 使用 Stellar 1.33.1 主题创建,一款很棒的 Hexo 主题!

总访问 次 || 本页访问
总访客 人 || 本页访客