がいつかオブジェクトの移動中にビットワイズコピーを最適化できますか?
struct Foo {
dummy: [u8; 65536],
}
fn bar(foo: Foo) {
println!("{:p}", &foo)
}
fn main() {
let o = Foo { dummy: [42u8; 65536] };
println!("{:p}", &o);
bar(o);
}
スニペットを検討プログラムの典型的なresultは
アドレスが異なる0x7fffc1239890
0x7fffc1229890
あります。
明らかに、大きな配列dummy
は、コンパイラの移動実装で期待どおりにコピーされています。残念ながら、dummy
は非常に大きな配列なので、これはパフォーマンスにはあまり影響しません。この影響は、関数が実際に引数を概念的に「消費」している場合でも、人々が代わりに参照渡しを選択するよう強制する可能性があります。
Foo
はCopy
を派生しないため、オブジェクトo
が移動されます。 Rustは移動オブジェクトのアクセスを禁止しているので、元のオブジェクトo
を "再利用"することを避けるために、コンパイラは潜在的に高価なビット単位のコピーを生成しますか?基本的な難しさはありますか、またはいつかコンパイラがこのビット単位のコピーを最適化するのを見ていきますか?
Rustcは動きを最適化します。この場合は、llvmがインラインバーを表示していなかったためです。これはポインターの値を観察しようとしていることが原因でもあり、llvmは最適化が安全かどうかはわかりません。私は ':p'の出力を使わずに試してみましたが、代わりにtest :: black_boxを使いました。そのコピーはアセンブリから消えてしまいました。 – Manishearth
@Manishearth 'bar'がインライン化しています。 LLVMは大規模な配列の移動を取り除くのが難しいだけです。 – Veedrac