【发布时间】:2017-02-19 20:39:07
【问题描述】:
我正在过度优化我的库,并且正在查看生成的 ASM。我注意到调用Arc<T> where T : MyTrait 的方法会产生一些我认为将存储在ArcInner 中的指针对齐到0x10 的东西。
我已经用这段代码复制了它:
#![feature(test)]
extern crate test;
use std::sync::Arc;
struct DA;
trait Drain {
fn log(&self, &DA);
}
struct BlackBoxDrain;
impl Drain for BlackBoxDrain {
fn log(&self, da: &DA) {
test::black_box::<&DA>(da);
}
}
fn f(d: Arc<Drain>) {
d.log(&DA)
}
fn main() {
let arc_d = Arc::new(BlackBoxDrain);
f(arc_d);
}
Rust playground(设置 Nightly + Release 并单击 ASM)
有问题的 ASM 代码是:
movq 16(%r15), %rdi
leaq 15(%rdi), %rax
negq %rdi
andq %rax, %rdi
addq %r14, %rdi
此操作必须尽可能快,这一点很重要。由于 ASM 取消引用是 5 条指令,其中 3 条似乎可能是不必要的,我想了解为什么会发生这种情况以及是否可以提供帮助。也许我只是不明白这里的汇编指令。
编辑:我的最小示例并不完全相同,因为看起来需要 crate 边界来防止编译器/链接器优化该序列。但是在我的例子中,顺序是完全相同的,在一个紧密的(rust bench)循环中,没有涉及到析构函数:只有 Arc<TraitObject> 上的方法调用。
【问题讨论】:
-
既然你在优化,你知道指令数量不一定与程序速度相关吗?例如,转到矢量化指令可能需要更多指令,但每个周期处理更多字节。
标签: assembly rust x86-64 micro-optimization