Tôi đã kiểm tra một số mã sử dụng các cờ /fp:precise
và /fp:fast
.Lạ/fp Dấu chấm động Hành vi mô hình điểm
Theo MSDN documentation cho /fp:precise
:
Với/fp: chính xác trên các bộ xử lý x86, trình biên dịch sẽ thực hiện làm tròn trên các biến kiểu float với độ chính xác thích hợp cho các bài tập và các cặn lắng và khi đi qua các tham số để một chức năng. Việc làm tròn này đảm bảo rằng dữ liệu không giữ lại bất kỳ ý nghĩa nào lớn hơn khả năng loại của nó. Một chương trình được biên dịch với/fp: chính xác có thể chậm hơn và lớn hơn một biên dịch không có/fp: chính xác./fp: chính xác vô hiệu hóa nội tại; các thói quen thư viện thời gian chạy chuẩn được sử dụng thay thế. Để biết thêm thông tin, xem/Oi (Generate Intrinsic Functions).
Nhìn vào tháo của một cuộc gọi đến sqrtf
(gọi với /arch:SSE2
, nhắm mục tiêu nền tảng x86/Win32
):
0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
Từ this question Tôi tin rằng các bộ xử lý x86/x64 hiện đại không sử dụng thanh ghi 80-bit (hoặc ít nhất là không khuyến khích sử dụng của họ) để trình biên dịch thực hiện những gì tôi sẽ giả định là điều tốt nhất tiếp theo và làm các phép tính với đôi 64-bit. Và vì nội tại bị vô hiệu hóa, có một cuộc gọi đến một hàm sqrtf của thư viện.
Ok, công bằng, điều này dường như tuân thủ những gì tài liệu nói.
Tuy nhiên, khi tôi biên dịch cho các kiến trúc x64, một cái gì đó kỳ lạ xảy ra:
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
Các tính toán không được thực hiện với đôi 64-bit, và intrinsics đang được sử dụng. Theo như tôi có thể nói, kết quả chính xác giống như cờ /fp:fast
được sử dụng.
Tại sao có sự khác biệt giữa hai? Không /fp:precise
chỉ đơn giản là không hoạt động với nền tảng x64?
Bây giờ, như một kiểm tra tính chính xác, tôi đã thử nghiệm cùng một mã trong VS2010 x86 với /fp:precise
và /arch:SSE2
. Đáng ngạc nhiên là, sqrtpd
nội tại đang được sử dụng!
00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
Điều gì đang xảy ra ở đây? Tại sao VS2010 sử dụng nội tại trong khi VS2012 gọi một thư viện hệ thống?
Thử nghiệm VS2010 nhắm mục tiêu nền tảng x64 có kết quả tương tự như VS2012 (/fp:precise
dường như bị bỏ qua).
Tôi không có quyền truy cập vào bất kỳ phiên bản cũ nào của VS nên tôi không thể thực hiện bất kỳ thử nghiệm nào trên các nền tảng này.
Để tham khảo, tôi đang thử nghiệm trong Windows 7 64 bit với bộ xử lý Intel i5-m430.
Điều này thật kỳ lạ. Tôi biết thực tế là '/ fp: exact' đôi khi sẽ khiến trình biên dịch quảng bá trung gian cho độ chính xác cao hơn theo ý mình. Nhưng điều đó không giải thích sự mâu thuẫn tuyệt đối ở đây. – Mysticial
"Từ câu hỏi này tôi tin rằng kiến trúc x86 không có thanh ghi 80 bit" Hãy đến một lần nữa? –
Vâng, từ ngữ kỳ lạ. Cập nhật để làm rõ các khuyến nghị chung chống lại việc sử dụng chúng. – helloworld922