2013-04-04 18 views
9

Tôi nhận ra sự khác biệt có thể là không đáng kể, nhưng đó là hiệu quả hơn trong cố gắng để không một unsigned dài?C/C++: có nhanh hơn khi gán một biến 0 cho một biến dài chưa ký hoặc để biến biến đó với chính nó?

unsigned long x; 

... 

x=0; 

--OR-- 

x^=x; 

Taylor

+5

Hoặc. Nhưng một là dễ đọc hơn. –

+5

Chọn cái đẹp hơn. – Mysticial

+2

Chọn đẹp hơn và để trình biên dịch tối ưu hóa nó cho bạn. – StoryTeller

Trả lời

30

Nếu bạn đã thực hiện một trình biên dịch, bạn sẽ làm gì? Thật vậy, bạn sẽ chọn triển khai nhanh nhất cho cả hai. Vì cả hai đều bằng nhau, việc triển khai nhanh nhất này giống nhau cho cả hai.

Nói cách khác, bất kỳ trình biên dịch nào được phát hành sau 5000 B.C. sẽ tạo cùng một mã assembly cho cả x = 0x ^= x nếu bạn bật tối ưu hóa. Điều này có nghĩa là chúng đều nhanh chóng.

Điều này không chỉ để chỉ định/xorring, mà còn cho multiplication, trong số các thuật toán khác. Thể hiện ý định của bạn và để trình biên dịch tối ưu hóa nó. Trình biên dịch tối ưu hóa tốt hơn bạn, hãy tin tôi đi.

Nói cách khác, hãy viết mã có thể đọc và sử dụng x = 0;.


Oh và bằng cách này, bitwise xorring một số nguyên chưa được khởi tạo bởi chính nó là hành vi không xác định và trình biên dịch tốt nên tối ưu hóa toàn bộ điều.

+11

Tôi upvoted nó, mặc dù câu hỏi là về C và không về COBOL: D – StoryTeller

11

Trước hết, nếu biến chưa được chỉ định một giá trị, đó là "hành vi không xác định" về mặt kỹ thuật "để làm bất cứ điều gì khác ngoài gán giá trị cho nó.

Thứ hai, để XOR nó với chính nó là không thể nhanh hơn trên một bộ xử lý sản xuất trong 15-20 năm qua, vì nó đòi hỏi phải đọc thêm. Nó có thể nhanh hơn (do bị mất mã) một thời gian rất dài, nhưng thực sự, tôi tin rằng ngay cả đó là sai.

Chỉnh sửa: Tôi nên chỉ ra rằng nó vẫn có thể nhanh hơn/gọn hơn để XOR đăng ký để làm cho nó bằng không trong bộ vi xử lý hiện đại. Nhưng nếu chúng ta giả định rằng chúng ta không thể biết nếu x có trong sổ đăng ký hay không, thì chúng ta cũng không nên làm cho nó phức tạp hơn đối với trình biên dịch để xác định những gì chúng ta đang thực sự làm.

+4

Trên thực tế, xoring một đăng ký với chính nó là cách tiêu chuẩn và nhanh nhất để không nó. Phần cứng hiện đại coi đó là trường hợp đặc biệt để tránh sự phụ thuộc đọc. Nó thường được giải quyết thông qua đăng ký đổi tên với một hồ sơ của số không đăng ký. – Mysticial

+0

Khi bạn đang viết, tôi đang chỉnh sửa câu trả lời ... –

+0

@Mysticial: Lưu ý rằng CPU khá thông minh về nó - ví dụ, nó không chỉ biết về 'xor rax, rax', mà còn 'sub rax, rax' để hai kết thúc thực hiện giống hệt nhau. –

2

Tại sao đầu cơ về trình biên dịch làm gì? Hãy thử nó ra thay!

Dưới đây là một số mã kiểm tra:

void fzero() 
{ 
    unsigned long x; 

    x = 0; 
} 

void fxor() 
{ 
    unsigned long x; 

    x ^= x; 
} 


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

Và bây giờ cho phép xem xét các kết quả mã máy:

; 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 

Oh, Nhìn kìa! Chúng đều nhanh như nhau, cả hai đều lấy chính xác 0 ns.

Các vấn đề liên quan