< 返回版块

洛佳 发表于 2022-02-09 13:50

Tags:riscv, 标准库

最近我在给stdarch库做贡献,遇到了这个问题。考虑在Linux下,Rust标准库的is_xxx_feature_detected!通常通过读取auxvec的方式获得当前进程环境支持的处理器功能。比如我检测处理器支不支持avx2,就使用getauxvec得到一个值,通过这个值某一位是否被设置为1,判断支不支持avx2。

但有些C语言的库比如OpenSSL的有些代码提供了另一种途径,它在Linux下可以捕捉非法指令信号,来达到类似的功能,而且检测会更精细。原理是先设置一个信号处理函数,然后执行指令集里的一条指令,如果它不存在,会发生非法指令,信号处理函数接收到,就设置返回值为指令集不存在,反之不会设置为不存在。

这种方法相比auxvec分别有一些优缺点。优点在可以检测更精细的指令集和CPU不提供检测方法的指令集,前者的例子比如RISC-V RVK的Zks,通过Auxvec只能检查是否存在K,而K下面有很多可选的模块,是无法通过这种方法检查的。后者的例子比如ARM7里的tick函数,它不能直接读Auxvec来检查。而缺点在于这个检测方法至少需要一次处理器中断,会花费更长的时间,能通过Auxvec检查的还是尽量通过Auxvec,实在不行再用信号法去检查。

如果Rust的标准库没有通过这种方法实现is_xxx_feature_detected!,会有哪些原因?更进一步地说,在内核模块开发或者裸机的Rust下(暂时不考虑没有std库只有core库),可以通过陷入返回法(和信号法类似,不过直接操作处理器的中断处理入口寄存器,我写了段代码来描述探测的过程)探测环境上的指令集,这时候仍然能使用这种方法就是有作用的。

评论区

写评论

还没有评论

1 共 0 条评论, 1 页