刚刚看褪黑素的瓶子上面写着吃完不要驾驶,突然想起来前天晚上吃完之后开美卡,最后一把药劲上来了撞了个损坏度 100%,看来确实没瞎说。
🥱5🤔2
Forwarded from 刘阳
box64 LA64 已经实现了
详情:https://github.com/ptitSeb/box64/pull/1425#issuecomment-2041074951
7z b 所需的所有指令,结果出炉:60% native,127% latx 1.4.4。详情:https://github.com/ptitSeb/box64/pull/1425#issuecomment-2041074951
👏7🤔1🤯1
https://github.com/DynamoRIO/dynamorio/pull/6691
DynamoRIO 最近增加了一个新的 fake ISA,支持在内部的 IR 和这个新 ISA 之间相互转换,所以用户就可以通过 IR 把 x86/ARM/RV64 的指令转成这个 fake ISA。这个东西乍看起来有点奇怪,仔细探究之后发现,他们是想用这个新的 ISA 来保存 traces 数据:
We want to create a new tool to filter traces of Google workloads for public release.
The new public Google workload traces will contain more information compared to the previous version, while still preserving confidentiality of Google's IP.
但是更重要的一点是,为了公开发布 traces 数据但不泄漏私研指令集的细节。。
DynamoRIO 最近增加了一个新的 fake ISA,支持在内部的 IR 和这个新 ISA 之间相互转换,所以用户就可以通过 IR 把 x86/ARM/RV64 的指令转成这个 fake ISA。这个东西乍看起来有点奇怪,仔细探究之后发现,他们是想用这个新的 ISA 来保存 traces 数据:
We want to create a new tool to filter traces of Google workloads for public release.
The new public Google workload traces will contain more information compared to the previous version, while still preserving confidentiality of Google's IP.
但是更重要的一点是,为了公开发布 traces 数据但不泄漏私研指令集的细节。。
GitHub
i#6662 public traces, part 1: synthetic ISA by edeiana · Pull Request #6691 · DynamoRIO/dynamorio
A synthetic ISA that has the purpose of preserving register dependencies and giving
hints on the type of operation an instruction performs. This PR implements the
encoding/decoding functionalities...
hints on the type of operation an instruction performs. This PR implements the
encoding/decoding functionalities...
mold debug 小计
今天开发 DynamoRIO RV64 终于受不了 GNU ld 慢出天际的性能,决定掏出 mold 来拯救一下:
然后就发现 mold 竟然 segfault 了,于是就开始了漫长的 debugging。之前给 mold 贡献过一点代码所以算是对 codebase 有一点了解,这方面没有花太多时间。
使用
在 backtrace 前后一通 print 后发现是一个名为
psABI 还规定了如果动态链接的可执行文件中包含
总结一下,
回到问题本身,一通瞎调试和漫长的编译等待后毫无头绪,我突然想到可以精简一下链接命令行,看看能不能缩小一下范围。最后发现只要尝试和某个 .so 链接就可以复现这个问题。然后我惊奇地发现这个 .so 竟然导出了
然后突然想起来同事的科普: .so 文件其实可以同时是一个可执行文件,比如你可以直接执行
这下问题就说通了,mold 在读取完输入的 object files 之后,会自己合成一堆符号,
总之,最后提交了如下 PR,解决方案是在读取 shared object 符号时,把所有读到的
https://github.com/rui314/mold/pull/1236
但不知道作者会不会接受这个 PR,因为可能存在更好的修复方式。
今天开发 DynamoRIO RV64 终于受不了 GNU ld 慢出天际的性能,决定掏出 mold 来拯救一下:
mold -run make -j4
然后就发现 mold 竟然 segfault 了,于是就开始了漫长的 debugging。之前给 mold 贡献过一点代码所以算是对 codebase 有一点了解,这方面没有花太多时间。
使用
gcc -v 打印出编译器 driver 调用链接器的命令行,替换成 mold 后运行复现了 segfault。于是 git clone 了 mold 的最新代码,debug build 之后挂上 gdb 拿到了 backtrace。在 backtrace 前后一通 print 后发现是一个名为
__global_pointer$ 的符号在做 COPYREL 时,因为对应的文件为空,所以触发了 segfault。__global_pointer$ 是 RISC-V psABI 中规定的一个由链接器在链接期合成的符号,指向 .sdata+0x800 的位置, gp 寄存器会在程序一开始执行的时候就被赋值为 __global_pointer$ 的值并且不会再变,所以用户程序可以方便地通过 gp 寄存器来快速访问 .sdata 数据。psABI 还规定了如果动态链接的可执行文件中包含
gp -relative 的内存访问,则 __global_pointer$ 必须导出到动态符号表中以供动态链接器使用。总结一下,
__global_pointer$ 由链接器合成,并且在满足条件时,需要导出到可执行文件中的动态符号表中。挺好,看起来没啥问题。回到问题本身,一通瞎调试和漫长的编译等待后毫无头绪,我突然想到可以精简一下链接命令行,看看能不能缩小一下范围。最后发现只要尝试和某个 .so 链接就可以复现这个问题。然后我惊奇地发现这个 .so 竟然导出了
__global_pointer$ 符号:
$ readelf -s -W xxx.so | grep __global_pointer$
75: 000000007131b5e4 0 NOTYPE GLOBAL DEFAULT ABS __global_pointer$
然后突然想起来同事的科普: .so 文件其实可以同时是一个可执行文件,比如你可以直接执行
/usr/lib/libc.so.6 ,所以动态链接库导出这个符号并不奇怪。这下问题就说通了,mold 在读取完输入的 object files 之后,会自己合成一堆符号,
__global_pointer$ 就是其中之一。但如果读取进来的 object files 已经存在了这个符号,就会和 mold 创建的合成符号产生冲突,那么出现什么问题也都不奇怪了。总之,最后提交了如下 PR,解决方案是在读取 shared object 符号时,把所有读到的
__global_pointer$ 过滤掉:https://github.com/rui314/mold/pull/1236
但不知道作者会不会接受这个 PR,因为可能存在更好的修复方式。
🤯3👍1🤔1
感谢 @sterpr1m 分享的 spike-dasm 跨架构平替,效果:
代码:
$ ./la64dasm 700be063
0: 700be063 vadd.d $vr3, $vr3, $vr24
代码:
$ cat la64dasm
#!/usr/bin/env bash
TEMP=$(mktemp)
echo $1 | tac -rs .. | echo "00000000: $(tr -d '\n')" | xxd -r > $TEMP
objdump -b binary -m Loongarch64 -D $TEMP | grep 0:
rm $TEMP
🥰4
如何用一天的时间实现 numpy RVV 支持
背景:
numpy 的基本架构是有一套 universal intrinsic,然后各个后端(比如 Neon、SSE)用自己的 intrinsic 去实现这个 universal 的。
方案一:
所以如果要增加 RVV 的支持,比较正统的做法就是增加一个 RVV 的后端,然后去实现这套 universal intrinsic。
但就目前情况来说,上游自己也觉得维护这么多后端的担子太重了,所以他们其实有砍掉整个 universal intrinsic,换用更加成熟的 google/highway 的想法。
这也决定了上游几乎不太可能接受一个巨大的 RVV backend patch 了,方案一属于费力不讨好。
方案二:
既然上游有用 highway 的意愿,那就帮助上游把所有用 universal intrinsic 写的函数都用 highway 重写一遍,因为 highway 支持 RVV,这样 numpy RVV 也就顺手支持了。
方案二最大的问题就是上游推进 highway 支持的进度非常慢,这对其他已有的后端几乎没有影响,但对于 RVV 来说就是有还是无的致命问题。
方案三:
那如果放弃提交上游,有没有更加快捷,不需要完整实现一个 RVV 后端的方法呢?
方案三就是今天要介绍的做法,neon2rvv[1] 是一个将 ARM Neon intrinsic 翻译成 RVV intrinsic 的兼容层,举个例子:
可以看到
因为 Neon 的寄存器是 128 位的,这就要求 vlen 必须大于等于 128 位,并且超出 128 位的部分会被完全浪费掉。
本着有总比没有强的原则,使用这个兼容层,我们就可以原地利用 Neon 后端来实现 RVV 后端了,理想情况下,要做的就只是
当然,理想情况并不存在,在实际的实现过程中,我发现了一些无法用 RVV 实现的 Neon intrinsic;neon2rvv 尚未实现的 intrinsic;neon2rvv bug 等等。
最终的结果就是:
numpy 加了一个很小的 patch [2],neon2rvv 提交了一个很小的 PR [3],numpy RVV 就有了初步的支持。
在新发布的 BananaPi F3(顺序 8 核,vlen=256) 上运行 pytest 结果如下:
可以看到,目前的支持度还是挺不错的,失败的都是一些比较极端的情况,还需要花更多时间来 debug。
做了一个简单的 benchmark,在
[1] https://github.com/howjmay/neon2rvv
[2] https://github.com/plctlab/numpy/commit/edee45e5e184d23929a605c9441607aca03a019a
[3] https://github.com/howjmay/neon2rvv/pull/396
背景:
numpy 的基本架构是有一套 universal intrinsic,然后各个后端(比如 Neon、SSE)用自己的 intrinsic 去实现这个 universal 的。
方案一:
所以如果要增加 RVV 的支持,比较正统的做法就是增加一个 RVV 的后端,然后去实现这套 universal intrinsic。
但就目前情况来说,上游自己也觉得维护这么多后端的担子太重了,所以他们其实有砍掉整个 universal intrinsic,换用更加成熟的 google/highway 的想法。
这也决定了上游几乎不太可能接受一个巨大的 RVV backend patch 了,方案一属于费力不讨好。
方案二:
既然上游有用 highway 的意愿,那就帮助上游把所有用 universal intrinsic 写的函数都用 highway 重写一遍,因为 highway 支持 RVV,这样 numpy RVV 也就顺手支持了。
方案二最大的问题就是上游推进 highway 支持的进度非常慢,这对其他已有的后端几乎没有影响,但对于 RVV 来说就是有还是无的致命问题。
方案三:
那如果放弃提交上游,有没有更加快捷,不需要完整实现一个 RVV 后端的方法呢?
方案三就是今天要介绍的做法,neon2rvv[1] 是一个将 ARM Neon intrinsic 翻译成 RVV intrinsic 的兼容层,举个例子:
uint32x2_t vadd_u32(uint32x2_t a, uint32x2_t b) {
return __riscv_vadd_vv_u32m1(a, b, 2);
}
可以看到
vadd_u32 和 __riscv_vadd_vv_u32m1 是一对一的翻译,当然也存在一对多的情况。因为 Neon 的寄存器是 128 位的,这就要求 vlen 必须大于等于 128 位,并且超出 128 位的部分会被完全浪费掉。
本着有总比没有强的原则,使用这个兼容层,我们就可以原地利用 Neon 后端来实现 RVV 后端了,理想情况下,要做的就只是
#include neon2rvv.h 。当然,理想情况并不存在,在实际的实现过程中,我发现了一些无法用 RVV 实现的 Neon intrinsic;neon2rvv 尚未实现的 intrinsic;neon2rvv bug 等等。
最终的结果就是:
numpy 加了一个很小的 patch [2],neon2rvv 提交了一个很小的 PR [3],numpy RVV 就有了初步的支持。
在新发布的 BananaPi F3(顺序 8 核,vlen=256) 上运行 pytest 结果如下:
237 failed, 42599 passed
可以看到,目前的支持度还是挺不错的,失败的都是一些比较极端的情况,还需要花更多时间来 debug。
做了一个简单的 benchmark,在
absolute_f32 上对比标量有 4 倍的性能提升。因为这台机器的 vlen 是 256,所以预期值应该是 8 倍,这里 4 倍是因为高 128 位完全没利用起来。[1] https://github.com/howjmay/neon2rvv
[2] https://github.com/plctlab/numpy/commit/edee45e5e184d23929a605c9441607aca03a019a
[3] https://github.com/howjmay/neon2rvv/pull/396
👍6
ksco 的工作日志
接下来是不是可以上 C-Reduce 了
跑出来了,精简到了 <60 行:https://ksco.cool/a/wnwr
edit:已交由同事提交到了 Debian:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1071140
edit:已交由同事提交到了 Debian:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1071140
🗿5