2013-04-04 8 views

Odpowiedz

30

Jeśli było wdrożenie kompilator, co byś zrobił? Rzeczywiście, wybrałbyś najszybszą implementację dla obu. Ponieważ obie są równe, ta najszybsza implementacja jest taka sama dla obu.

Innymi słowy, każdy kompilator wydany po 5000 B.C. wygeneruje ten sam kod zespołu dla obu x = 0 i x ^= x, jeśli włączysz optymalizacje. Oznacza to, że są one równie szybkie.

To nie dotyczy tylko przypisania/xorring, ale także dla innych algorytmów: multiplication. Wyraź swoją intencję i pozwól, aby kompilator ją zoptymalizował. Kompilator jest lepszy w optymalizacji niż ty, zaufaj mi.

Innymi słowy, napisz czytelny kod i użyj x = 0;.


No i przy okazji, bitwise xorring niezainicjowanej całkowitą sama jest niezdefiniowane zachowanie i dobry kompilator powinien optymalizować się całą rzecz.

+11

Podniosłem to, mimo że pytanie dotyczyło C, a nie COBOL: D – StoryTeller

11

Po pierwsze, jeśli zmiennej nie przypisano żadnej wartości, technicznie "niezdefiniowane zachowanie" oznacza cokolwiek innego niż przypisanie jej wartości.

Po drugie, dla XOR jest mało prawdopodobne, aby był szybszy na procesorze wyprodukowanym w ciągu ostatnich 15-20 lat, ponieważ wymaga dodatkowej lektury. Być może było to szybsze (z powodu bycia SHORTER CODE) bardzo długo, ale w rzeczywistości, wierzę, że nawet to jest fałszywe.

Edycja: Powinienem wskazać, że MOŻE być nadal szybszy/bardziej kompaktowy, aby XOR był rejestrem, aby był równy zeru we współczesnych procesorach. Ale jeśli założymy, że nie możemy się dowiedzieć, czy x jest w rejestrze, czy nie, nie powinniśmy również komplikować bardziej skomplikowanego kompilatora w celu ustalenia, co faktycznie robimy.

+4

W rzeczywistości, xoring rejestru ze sobą jest standardową i najszybszą drogą do zera to. Nowoczesny sprzęt traktuje to jako specjalny przypadek, aby uniknąć zależności odczytu. Najczęściej jest rozwiązywany poprzez zmianę nazwy rejestru przy pomocy puli zerowych rejestrów. – Mysticial

+0

Podczas pisania tego, edytowałem swoją odpowiedź ... –

+0

@Mysticial: Zauważ, że CPU jest dość sprytny - na przykład, nie tylko zna "xor rax, rax", ale także 'sub rax, rax', więc dwa kończą się identycznie. –

2

Po co spekulować na temat tego, co robi kompilator? Spróbujmy zamiast tego!

Oto niektóre kodu testu:

void fzero() 
{ 
    unsigned long x; 

    x = 0; 
} 

void fxor() 
{ 
    unsigned long x; 

    x ^= x; 
} 


int main() 
{ 
    fzero(); 
    fxor(); 
} 

A teraz spójrzmy na wynikowego kodu maszynowego:

; 10 : unsigned long x; 
; 11 : 
; 12 : x ^= x; 
; 13 : } 

00000 c2 00 00  ret  0 

; 3 : unsigned long x; 
; 4 : 
; 5 : x = 0; 
; 6 : } 

00000 c2 00 00  ret  0 

PUBLIC main 
; Function compile flags: /Ogtpy 
; COMDAT main 
_TEXT SEGMENT 
main PROC      ; COMDAT 

; 18 : fzero(); 
; 19 : fxor(); 
; 20 : } 

    00000 33 c0  xor  eax, eax 
    00002 c3  ret  0 
main ENDP 

Och, patrzcie! Były równie szybkie, obie miały dokładnie 0 ns.

Powiązane problemy