Thật không may là bạn đã chọn một ví dụ xấu. Trình biên dịch JIT x86 không phải là các phương thức inline trả về float. Không chắc chắn 100% lý do tại sao, tôi nghĩ rằng nó để tránh những vấn đề nhất quán khi phao được chuyển đổi thành một giá trị dấu phẩy động 80 bit trong FPU. Độ chính xác nội bộ là 80 bit nhưng các bit phụ này bị cắt bớt khi giá trị 80 bit bị cắt ngắn trở lại giá trị 32 bit khi nó được xóa trở lại bộ nhớ. Việc giữ giá trị trong FPU quá lâu sẽ ngăn chặn việc cắt ngắn này xảy ra và thay đổi kết quả tính toán.
Nếu bạn thay thế phao bằng cách double và biên dịch mã này:
static void Main(string[] args) {
Console.WriteLine(Cube(2.0));
}
Sau đó, mã máy tính này được tạo ra khi tôi ưu JIT được kích hoạt:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 call 6DA2BEF0 ; Console.get_Out()
00000008 fld qword ptr ds:[010914B0h] ; ST0 = 8.0
0000000e sub esp,8 ; setup argument for WriteLine
00000011 fstp qword ptr [esp]
00000014 mov ecx,eax ; call Console.Out.WriteLine
00000016 mov eax,dword ptr [ecx]
00000018 call dword ptr [eax+000000D0h]
0000001e pop ebp ; done
0000001f ret
không chỉ nó nội tuyến chức năng, nó đã có thể đánh giá các biểu thức tại thời gian biên dịch. Và trực tiếp vượt qua kết quả bằng cách gọi Console.WriteLine (8.0). Khá tốt huh?
Sử dụng kép, không nổi.
Nguồn
2010-07-31 15:12:24
Thú vị ... vì tôi đang làm việc ở XNA nơi * mọi thứ * là một phao! Hơi liên quan đến ... –
* "Trình biên dịch JIT x86 không phải là các phương thức inline trả về float." * - Bạn có chắc chắn về điều này không? Tôi đã tìm kiếm cao và thấp và không thể tìm thấy bất kỳ tài liệu tham khảo để trở lại này lên. Điều tốt nhất tôi thấy là trang này trên Connect: https://connect.microsoft.com/VisualStudio/feedback/details/536781/unexpected-jit-inlining-behavior mà dường như ngụ ý rằng các hàm trả về float * do *, trên thực tế, nội tuyến. Và bài báo (cũ) này ngụ ý rằng các quy tắc ép buộc (có thể khác nhau trong thực tế) là giống nhau đối với phao và đôi: http://blogs.msdn.com/b/davidnotario/archive/2005/08/08/449092. aspx –
@Andrew: các quy tắc nội tuyến không được ghi lại, chỉ được đề cập trong một số bài đăng trên blog. Quan trọng, bởi vì họ cần để có thể thay đổi điều này để cải thiện jitter mà không vi phạm các giả định được thực hiện từ hành vi tài liệu. Tôi chỉ có thể ghi lại những gì tôi thấy jitter x86 của tôi làm. Và nó chắc chắn không inline phiên bản float của những phương thức này. Bạn có thấy hành vi khác nhau không? –