7

我很想知道 MIPS 代码、GCC 或 LLVM 的“最佳”免费/OSS 编译器是什么,或者有什么比这些更好的吗?

我有兴趣了解更多关于快速和内存受限生成的汇编代码而不是代码大小的信息。

换句话说,llvm-opt 是否比 gcc -O3 做得更好?

4

3 回答 3

2

http://www.phoronix.com/scan.php?page=news_item&px=OTI1MA “LLVM 2.9 Release Candidate 2 在这里

Michael Larabel 于 2011 年 3 月 25 日发表,由于缺乏硬件,没有 LLVM ARM 基准测试......”

也许具有快速双臂/四臂皮质和 LLVM ARM 等的人可以在周一之前运行http://openbenchmarking.org/ bench,Michael 可以将这些添加到他的其他结果中

于 2011-03-26T20:11:51.917 回答
1

我不知道 mips,我尝试了 ARM,llvm 代码比当前的 gcc 慢了大约 10-20%。有问题的测试是基于 zlib 的。自身解压,压缩后解压。同时使用了 clang 和 llvm-gcc。我更喜欢 clang,因为 -m32 实际上适用于 64 位主机。对于有问题的测试,我发现不使用 -O2(或 -O3)产生最快的代码。将字节码模块链接到一个大模块中,并使用标准优化执行一次选择,以获得最快的代码。llc 默认为 -O2,这确实有助于提高性能。

编辑:

gcc 和 llvm/clang 之间对 mips 的有趣测试。

void dummy ( unsigned int );
void dowait ( void )
{
    unsigned int ra;
    for(ra=0x80000;ra;ra--) dummy(ra);
}

gcc 制作:

9d006034 <dowait>:
9d006034:   27bdffe8    addiu   sp,sp,-24
9d006038:   afb00010    sw  s0,16(sp)
9d00603c:   afbf0014    sw  ra,20(sp)
9d006040:   3c100008    lui s0,0x8
9d006044:   02002021    move    a0,s0
9d006048:   0f40180a    jal 9d006028 <dummy>
9d00604c:   2610ffff    addiu   s0,s0,-1
9d006050:   1600fffd    bnez    s0,9d006048 <dowait+0x14>
9d006054:   02002021    move    a0,s0
9d006058:   8fbf0014    lw  ra,20(sp)
9d00605c:   8fb00010    lw  s0,16(sp)
9d006060:   03e00008    jr  ra
9d006064:   27bd0018    addiu   sp,sp,24

和 llvm 组装后

9d006034 <dowait>:
9d006034:   27bdffe8    addiu   sp,sp,-24
9d006038:   afbf0014    sw  ra,20(sp)
9d00603c:   afb00010    sw  s0,16(sp)
9d006040:   3c020008    lui v0,0x8
9d006044:   34440000    ori a0,v0,0x0
9d006048:   2490ffff    addiu   s0,a0,-1
9d00604c:   0f40180a    jal 9d006028 <dummy>
9d006050:   00000000    nop
9d006054:   00102021    addu    a0,zero,s0
9d006058:   1600fffb    bnez    s0,9d006048 <dowait+0x14>
9d00605c:   00000000    nop
9d006060:   8fb00010    lw  s0,16(sp)
9d006064:   8fbf0014    lw  ra,20(sp)
9d006068:   27bd0018    addiu   sp,sp,24
9d00606c:   03e00008    jr  ra
9d006070:   00000000    nop

我在组装后说是因为我看到了 gnu-as do things like this

.globl PUT32
PUT32:
    sw $a1,0($a0)
    jr $ra
    nop

并为我重新安排组装:

9d00601c <PUT32>:
9d00601c:   03e00008    jr  ra
9d006020:   ac850000    sw  a1,0(a0)
9d006024:   00000000    nop

llvm 和 gcc 生成的代码之间的区别在于将指令放置在分支延迟槽中。我使用 clang 和 llc 生成程序集输出,然后使用 binutils、gnu as 创建二进制文件。因此,对于我的手工组装代码来说,这是一种好奇心:

ori $sp,$sp,0x2000
jal notmain
nop

它为我优化:

9d006004:   0f401820    jal 9d006080 <notmain>
9d006008:   37bd2000    ori sp,sp,0x2000
9d00600c:   00000000    nop

但是 llc 生成的代码

addiu   $16, $4, -1
jal dummy
nop

不是

9d006048:   2490ffff    addiu   s0,a0,-1
9d00604c:   0f40180a    jal 9d006028 <dummy>
9d006050:   00000000    nop
于 2009-07-21T19:29:32.780 回答
-1

LLVM 在 x86 上通常比 GCC 好,但我还没有找到任何 MIPS 基准。因为您在问这个问题,所以我假设您可以访问 MIPS 机器,那么您为什么不使用 GCC 和 LLVM 编译计算机语言基准游戏 C 代码,看看哪个更快。我猜 GCC 会是,因为 MIPS 后端相对较新,但代码更干净,我希望 LLVM 最终获胜。

于 2009-04-09T15:06:22.343 回答