Bildiğim kadarıyla, referans / işaretçi takma adı, derleyicinin optimize edilmiş kod üretme yeteneğini engelleyebilir, çünkü iki referansın / işaretçinin gerçekten takma adda oluşturulduğu ikili kodun doğru şekilde davranmasını sağlamalıdırlar. Örneğin, aşağıdaki C kodunda,
void adds(int *a, int *b) {
*a += *b;
*a += *b;
}
bayrak clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
ile derlendiğinde -O3
,
0000000000000000 <adds>:
0: 8b 07 mov (%rdi),%eax
2: 03 06 add (%rsi),%eax
4: 89 07 mov %eax,(%rdi) # The first time
6: 03 06 add (%rsi),%eax
8: 89 07 mov %eax,(%rdi) # The second time
a: c3 retq
Burada kod (%rdi)
durumda int *a
ve int *b
takma adda iki kez geri saklar .
Derleyiciye bu iki işaretçinin restrict
anahtar kelime ile takma ad veremeyeceğini açıkça söylediğimizde :
void adds(int * restrict a, int * restrict b) {
*a += *b;
*a += *b;
}
Ardından Clang, ikili kodun daha optimize bir sürümünü yayınlayacaktır:
0000000000000000 <adds>:
0: 8b 06 mov (%rsi),%eax
2: 01 c0 add %eax,%eax
4: 01 07 add %eax,(%rdi)
6: c3 retq
Rust (güvenli olmayan kod hariç) iki değişken referansın diğer adı kullanamayacağından emin olduğundan, derleyicinin kodun daha optimize edilmiş sürümünü yayınlayabilmesi gerektiğini düşünürdüm.
Aşağıda koduyla test etmek ve onu derlerken rustc 1.35.0
ile -C opt-level=3 --emit obj
,
#![crate_type = "staticlib"]
#[no_mangle]
fn adds(a: &mut i32, b: &mut i32) {
*a += *b;
*a += *b;
}
oluşturur:
0000000000000000 <adds>:
0: 8b 07 mov (%rdi),%eax
2: 03 06 add (%rsi),%eax
4: 89 07 mov %eax,(%rdi)
6: 03 06 add (%rsi),%eax
8: 89 07 mov %eax,(%rdi)
a: c3 retq
Bu garanti bu avantajı almaz a
ve b
olamaz takma.
Bunun nedeni, şu anki Rust derleyicisinin hala geliştirilme aşamasında olması ve optimizasyonu yapmak için henüz takma ad analizi içermemesi mi?
Bu hala bir şans çünkü olduğunu a
ve b
could bile güvenli Rust takma?
unsafe
kodda bile , takma değiştirilebilir referanslara izin verilmediğinden ve tanımlanmamış davranışla sonuçlandığından bahsetmek gerekir . Ham işaretçileri takma adlandırabilirsiniz, ancak unsafe
kod aslında Rust standart kurallarını yok saymanıza izin vermez. Bu sadece yaygın bir yanlış anlamadır ve bu yüzden belirtmeye değer.
+=
vücudundaki iki işlemin adds
yeniden yorumlanıp yorumlanamayacağı kaygılıyor *a = *a + *b + *b
. İşaretçileri takma yoksa, bunlar, hatta ne miktarda görebilirsiniz olabilir b* + *b
listeleme ikinci asm: 2: 01 c0 add %eax,%eax
. Ancak takma ad yaparlarsa, yapamazlar, çünkü *b
ikinci kez eklediğiniz zaman, 4:
ilk defadan farklı bir değer içerecektir ( ilk asm listesinin satırında sakladığınız değer ).