2013-05-10 25 views
33

Điều này question thể hiện một hiện tượng rất thú vị: denormalized phao làm chậm mã nhiều hơn một bậc độ lớn.Tại sao MSVS không tối ưu hóa +0? Thay vào đó, nó biến nó thành một phao không chuẩn hóa?

Hành vi này được giải thích rõ trong số accepted answer. Tuy nhiên, có một nhận xét, hiện tại có 48 phiếu bầu, tôi không thể tìm thấy câu trả lời thỏa đáng cho:

Tại sao trình biên dịch không thả +/- 0 trong trường hợp này?!? - Michael Dorgan

Side lưu ý: Tôi có ấn tượng rằng 0f là/phải chính xác biểu diễn (hơn nữa - đó là biểu diễn nhị phân phải tất cả zero), nhưng không thể tìm thấy như một tuyên bố trong tiêu chuẩn c11. Một báo giá chứng minh điều này, hoặc lập luận bác bỏ tuyên bố này, sẽ được chào đón nhiều nhất. Bất kể, Câu hỏi của Michael là câu hỏi chính ở đây.


§5.2.4.2.2

An thực hiện có thể cung cấp cho zero và giá trị mà không phải là dấu chấm động số (ví dụ như infinities và Nans) là một dấu hiệu hoặc có thể để lại cho họ unsigned.

+8

Điều này được trả lời trong một trong những nhận xét cuối cùng trong [câu trả lời] (http://stackoverflow.com/a/9314926/12711) cho câu hỏi được liên kết: "@ s73v3r: + 0.f không thể được tối ưu hóa bởi vì dấu phẩy động có 0 âm và kết quả của việc thêm + 0.f vào -.0f là + 0.f. Vì vậy, việc thêm 0.f không phải là một hoạt động nhận dạng và không thể được tối ưu hóa.- Eric Postpischil " –

+1

Và để được rõ ràng - nó không phải là' + 0.f' hoặc '-0.f' được denormalized - đó là giá trị trong mảng mà số không được thêm vào đó là không chuẩn hóa (và gây ra sự chậm lại –

+0

@Michael Burr, xem bản chỉnh sửa của tôi.Bằng cách này, bạn có nghĩ rằng bản in nhỏ trong câu hỏi là chính xác không? Hoặc tôi có nên hỏi câu hỏi này là một câu hỏi riêng không? – Vorac

Trả lời

40

Trình biên dịch không thể loại bỏ việc bổ sung một số không dương bằng dấu phẩy động vì nó không phải là hoạt động nhận dạng. Theo quy tắc IEEE 754, kết quả của việc thêm +0. đến -0. không phải là -0 .; nó là +0.

Trình biên dịch có thể loại trừ phép trừ của +0. hoặc thêm -0. bởi vì đó là những hoạt động nhận dạng.

Ví dụ, khi tôi biên dịch này:

double foo(double x) { return x + 0.; } 

với Apple GNU C 4.2.1 sử dụng -O3 trên Intel Mac, mã lắp ráp kết quả chứa addsd LC0(%rip), %xmm0. Khi tôi biên soạn điều này:

double foo(double x) { return x - 0.; } 

không có hướng dẫn thêm; assembly chỉ trả về đầu vào của nó.

Vì vậy, có khả năng mã trong câu hỏi ban đầu chứa một lệnh add cho tuyên bố này:

y[i] = y[i] + 0; 

nhưng không chứa hướng dẫn cho tuyên bố này:

y[i] = y[i] - 0; 

Tuy nhiên, báo cáo kết quả đầu tiên liên quan đến số học với các giá trị bình thường trong y[i], do đó, nó đủ để làm chậm chương trình.

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