2013-04-26 30 views
6

EDIT: Thật vậy, tôi đã có một lỗi lạ trong mã thời gian của tôi dẫn đến những kết quả này. Khi tôi sửa lỗi, phiên bản thông minh đã kết thúc nhanh hơn như mong đợi. Mã thời gian của tôi trông giống như sau:Nhà điều hành XOR chậm

bool x = false; 
before = now(); 
for (int i=0; i<N; ++i) { 
    x ^= smart_xor(A[i],B[i]); 
} 
after = now(); 

Tôi đã thực hiện ^= để ngăn cản trình biên dịch tối ưu hóa vòng lặp for. Nhưng tôi nghĩ rằng ^= bằng cách nào đó tương tác một cách kỳ lạ với hai hàm xor. Tôi đã thay đổi mã thời gian của mình để chỉ cần điền vào một mảng các kết quả xor, và sau đó thực hiện tính toán với mảng đó bên ngoài mã thời gian. Và những thứ cố định đó.

Tôi có nên xóa câu hỏi này không?

END EDIT

tôi xác định hai C++ chức năng như sau:

bool smart_xor(bool a, bool b) { 
    return a^b; 
} 

bool dumb_xor(bool a, bool b) { 
    return a?!b:b; 
} 

kiểm tra thời gian của tôi chỉ ra rằng dumb_xor() là nhanh hơn một chút (1.31ns vs 1.90ns khi sắp xếp theo hàng 1.92ns vs 2.21ns khi không nội tuyến). Điều này giải đố tôi, vì toán tử ^ phải là một thao tác đơn lẻ. Tôi tự hỏi nếu có ai có lời giải thích.

Việc lắp ráp trông như thế này (khi không inlined):

.file "xor.cpp" 
    .text 
    .p2align 4,,15 
.globl _Z9smart_xorbb 
    .type _Z9smart_xorbb, @function 
_Z9smart_xorbb: 
.LFB0: 
    .cfi_startproc 
    .cfi_personality 0x3,__gxx_personality_v0 
    movl %esi, %eax 
    xorl %edi, %eax 
    ret 
    .cfi_endproc 
.LFE0: 
    .size _Z9smart_xorbb, .-_Z9smart_xorbb 
    .p2align 4,,15 
.globl _Z8dumb_xorbb 
    .type _Z8dumb_xorbb, @function 
_Z8dumb_xorbb: 
.LFB1: 
    .cfi_startproc 
    .cfi_personality 0x3,__gxx_personality_v0 
    movl %esi, %edx 
    movl %esi, %eax 
    xorl $1, %edx 
    testb %dil, %dil 
    cmovne %edx, %eax 
    ret 
    .cfi_endproc 
.LFE1: 
    .size _Z8dumb_xorbb, .-_Z8dumb_xorbb 
    .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" 
    .section  .note.GNU-stack,"",@progbits 

Tôi đang sử dụng g ++ 4.4.3-4ubuntu5 trên bộ xử lý Intel Xeon X5570. Tôi biên soạn với -O3.

+0

nano giây có thể quá nhỏ để thực hiện bất kỳ so sánh có ý nghĩa nào. – yngccc

+2

Bạn có thể cần hiển thị mã thời gian của mình. Đó là dễ dàng để có được sai. –

+2

Tôi muốn 'a! = B' trên' a?! B: b'. – Pubby

Trả lời

4

Vì mã "câm XOR" của bạn dài hơn đáng kể (và hầu hết các hướng dẫn phụ thuộc vào mã trước đó, vì vậy nó sẽ không chạy song song), tôi nghi ngờ rằng bạn có một số lỗi đo lường trong kết quả của mình.

Trình biên dịch sẽ cần phải đưa ra hai hướng dẫn cho phiên bản out of line của "thông minh XOR" vì thanh ghi rằng dữ liệu đến không phải là thanh ghi để cung cấp kết quả trả về, vì vậy dữ liệu phải chuyển từ EDI và ESI sang EAX. Trong một phiên bản nội tuyến, mã sẽ có thể sử dụng bất cứ điều gì đăng ký dữ liệu là trong trước khi cuộc gọi, và nếu mã cho phép nó, kết quả nằm trong sổ đăng ký nó đến như.

Gọi chức năng nằm ngoài dòng có lẽ ít nhất là dài trong thời gian thực thi dưới dạng mã thực tế trong hàm.

Sẽ hữu ích nếu bạn thể hiện khai thác thử nghiệm mà bạn sử dụng để đo điểm chuẩn ...

5

Tôi không nghĩ rằng bạn đã đánh giá chính xác mã của mình.

Chúng ta có thể nhìn thấy trong lắp ráp tạo ra rằng chức năng smart_xor của bạn là:

movl %esi, %eax 
xorl %edi, %eax 

trong khi chức năng dumb_xor của bạn là:

movl %esi, %edx 
movl %esi, %eax 
xorl $1, %edx 
testb %dil, %dil 
cmovne %edx, %eax 

Vì vậy, rõ ràng, người đầu tiên sẽ nhanh hơn.
Nếu không, thì bạn có vấn đề đo điểm chuẩn.

Vì vậy, bạn có thể muốn điều chỉnh mã điểm chuẩn của mình ... Và hãy nhớ rằng bạn sẽ cần phải chạy nhiều cuộc gọi để có mức trung bình tốt và có ý nghĩa.