Hoạt động của điểm nổi C# /. NET có khác biệt chính xác giữa chế độ gỡ lỗi và chế độ phát hành không?Độ chính xác cao/kép ở chế độ gỡ lỗi/giải phóng
Trả lời
Họ thực sự có thể khác nhau. Theo đặc tả CLR ECMA:
địa điểm lưu trữ cho dấu chấm động số (tĩnh học, các phần tử mảng, và lĩnh vực lớp) có kích thước cố định. Kích thước bộ nhớ được hỗ trợ là float32 và float64. Ở mọi nơi khác (trên ngăn xếp đánh giá, dưới dạng các đối số , dưới dạng các loại trả về và biến cục bộ) số được thể hiện bằng cách sử dụng loại dấu phẩy động bên trong . Trong mỗi ví dụ , loại danh nghĩa của biến hoặc biểu thức hoặc là R4 hoặc R8, nhưng giá trị của nó có thể được biểu thị nội bộ với phạm vi bổ sung và/hoặc độ chính xác. Kích thước của biểu diễn dấu phẩy động bên trong phụ thuộc vào việc triển khai thực hiện, có thể thay đổi, và phải có độ chính xác ít nhất là tuyệt vời như biểu thức hoặc biểu thức . An chuyển đổi mở rộng tiềm ẩn sang biểu diễn nội bộ từ float32 hoặc float64 được thực hiện khi các loại này được tải từ bộ nhớ. Các đại diện nội bộ thường là kích thước gốc cho phần cứng, hoặc theo yêu cầu để thực hiện một hoạt động hiệu quả .
Điều này về cơ bản có nghĩa là sự so sánh sau đây có thể hoặc có thể không bằng nhau:
class Foo
{
double _v = ...;
void Bar()
{
double v = _v;
if(v == _v)
{
// Code may or may not execute here.
// _v is 64-bit.
// v could be either 64-bit (debug) or 80-bit (release) or something else (future?).
}
}
}
nhắn Take-nhà: không bao giờ kiểm tra các giá trị nổi cho sự bình đẳng.
Điều đó không liên quan gì đến DEBUG vs RELEASE xây dựng cấu hình mặc dù ... –
IL được tạo ra sẽ giống nhau ... nhưng JITter ít hung hăng hơn khi giao dịch với một assembly được đánh dấu là debug. Bản phát hành bản phát hành có xu hướng di chuyển nhiều giá trị nổi hơn vào thanh ghi 80 bit; gỡ lỗi xây dựng có xu hướng đọc trực tiếp từ bộ nhớ 64-bit lưu trữ. – stusmith
IL được tạo ra có thể không giống nhau. chế độ gỡ lỗi chèn nops ở những nơi để đảm bảo một breakpoint là có thể, nó cũng có thể cố tình duy trì một biến tạm thời mà chế độ phát hành có vẻ không cần thiết. – ShuggyCoUk
Chúng phải giống nhau. Số điểm nổi được dựa trên IEEE_754 standard.
Thực tế, chúng có thể khác nếu chế độ gỡ lỗi sử dụng FPU x87 và chế độ phát hành sử dụng SSE cho float-op.
Bạn có tài liệu tham khảo hoặc trình diễn có thẩm quyền không? –
Để đối phó với yêu cầu Frank Krueger của trên (trong ý kiến) cho một cuộc biểu tình của một sự khác biệt:
Biên dịch mã này trong gcc không có tối ưu hóa và -mfpmath = 387 (Tôi không có lý do gì để nghĩ rằng nó sẽ không làm việc trên các trình biên dịch khác, nhưng tôi đã không thử nó.) Sau đó biên dịch nó không có tối ưu hóa và -msse -mfpmath = sse.
Kết quả sẽ khác nhau.
#include <stdio.h>
int main()
{
float e = 0.000000001;
float f[3] = {33810340466158.90625,276553805316035.1875,10413022032824338432.0};
f[0] = pow(f[0],2-e); f[1] = pow(f[1],2+e); f[2] = pow(f[2],-2-e);
printf("%s\n",f);
return 0;
}
Câu hỏi là về C# /. Net; Ví dụ của bạn là cho C++/mã gốc. –
Bằng cách nào đó tôi nghi ngờ rằng độ chính xác của SSE vs x87 FPU khác nhau tùy thuộc vào ngôn ngữ bạn gọi nó từ! –
Một bản dịch trực tiếp sang C# cũng hiển thị các kết quả khác nhau cho x86 và x64 trong Visual Studio 2013. Lưu ý rằng x86 CLR sử dụng x87 FPU trong khi x64 CLR sử dụng SSE. – Asik
Thanks guys Tôi tìm thấy một vài điều gì nói những gì trong làm hành vi phao sẽ khác nhau trong chế độ phát hành
http://blogs.msdn.com/davidnotario/archive/2005/08/08/449092.aspx
Đây là một câu hỏi thú vị, vì vậy tôi đã làm một chút thử nghiệm.Tôi đã sử dụng mã này:
static void Main (string [] args)
{
float
a = float.MaxValue/3.0f,
b = a * a;
if (a * a < b)
{
Console.WriteLine ("Less");
}
else
{
Console.WriteLine ("GreaterEqual");
}
}
sử dụng DevStudio 2005 và Net 2. Tôi biên soạn như cả hai gỡ lỗi và phát hành và kiểm tra đầu ra của trình biên dịch:
Release Debug
static void Main (string [] args) static void Main (string [] args)
{ {
00000000 push ebp
00000001 mov ebp,esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp,3Ch
00000009 xor eax,eax
0000000b mov dword ptr [ebp-10h],eax
0000000e xor eax,eax
00000010 mov dword ptr [ebp-1Ch],eax
00000013 mov dword ptr [ebp-3Ch],ecx
00000016 cmp dword ptr ds:[00A2853Ch],0
0000001d je 00000024
0000001f call 793B716F
00000024 fldz
00000026 fstp dword ptr [ebp-40h]
00000029 fldz
0000002b fstp dword ptr [ebp-44h]
0000002e xor esi,esi
00000030 nop
float float
a = float.MaxValue/3.0f, a = float.MaxValue/3.0f,
00000000 sub esp,0Ch 00000031 mov dword ptr [ebp-40h],7EAAAAAAh
00000003 mov dword ptr [esp],ecx
00000006 cmp dword ptr ds:[00A2853Ch],0
0000000d je 00000014
0000000f call 793B716F
00000014 fldz
00000016 fstp dword ptr [esp+4]
0000001a fldz
0000001c fstp dword ptr [esp+8]
00000020 mov dword ptr [esp+4],7EAAAAAAh
b = a * a; b = a * a;
00000028 fld dword ptr [esp+4] 00000038 fld dword ptr [ebp-40h]
0000002c fmul st,st(0) 0000003b fmul st,st(0)
0000002e fstp dword ptr [esp+8] 0000003d fstp dword ptr [ebp-44h]
if (a * a < b) if (a * a < b)
00000032 fld dword ptr [esp+4] 00000040 fld dword ptr [ebp-40h]
00000036 fmul st,st(0) 00000043 fmul st,st(0)
00000038 fld dword ptr [esp+8] 00000045 fld dword ptr [ebp-44h]
0000003c fcomip st,st(1) 00000048 fcomip st,st(1)
0000003e fstp st(0) 0000004a fstp st(0)
00000040 jp 00000054 0000004c jp 00000052
00000042 jbe 00000054 0000004e ja 00000056
00000050 jmp 00000052
00000052 xor eax,eax
00000054 jmp 0000005B
00000056 mov eax,1
0000005b test eax,eax
0000005d sete al
00000060 movzx eax,al
00000063 mov esi,eax
00000065 test esi,esi
00000067 jne 0000007A
{ {
Console.WriteLine ("Less"); 00000069 nop
00000044 mov ecx,dword ptr ds:[0239307Ch] Console.WriteLine ("Less");
0000004a call 78678B7C 0000006a mov ecx,dword ptr ds:[0239307Ch]
0000004f nop 00000070 call 78678B7C
00000050 add esp,0Ch 00000075 nop
00000053 ret }
} 00000076 nop
else 00000077 nop
{ 00000078 jmp 00000088
Console.WriteLine ("GreaterEqual"); else
00000054 mov ecx,dword ptr ds:[02393080h] {
0000005a call 78678B7C 0000007a nop
} Console.WriteLine ("GreaterEqual");
} 0000007b mov ecx,dword ptr ds:[02393080h]
00000081 call 78678B7C
00000086 nop
}
gì các chương trình trên là sự nổi mã điểm là như nhau cho cả hai gỡ lỗi và phát hành, trình biên dịch được lựa chọn nhất quán hơn tối ưu hóa. Mặc dù chương trình tạo ra kết quả sai (a * a không nhỏ hơn b) nó giống nhau bất kể chế độ gỡ lỗi/phát hành.
Bây giờ, FPU Intel IA32 có 8 thanh ghi dấu chấm động, bạn sẽ nghĩ trình biên dịch sẽ sử dụng thanh ghi để lưu trữ giá trị khi tối ưu hóa thay vì ghi vào bộ nhớ, do đó cải thiện hiệu suất, điều gì đó dọc theo các dòng:
fld dword ptr [a] ; precomputed value stored in ram == float.MaxValue/3.0f
fmul st,st(0) ; b = a * a
; no store to ram, keep b in FPU
fld dword ptr [a]
fmul st,st(0)
fcomi st,st(0) ; a*a compared to b
nhưng điều này sẽ thực thi khác với phiên bản gỡ lỗi (trong trường hợp này, hiển thị kết quả chính xác). Tuy nhiên, thay đổi hành vi của chương trình tùy thuộc vào các tùy chọn xây dựng là một điều rất xấu.
Mã FPU là một lĩnh vực mà việc tạo thủ công mã có thể thực hiện tốt hơn đáng kể trình biên dịch, nhưng bạn cần phải thu hút đầu của bạn xung quanh cách FPU hoạt động.
- 1. Gỡ lỗi Emacs Lisp chế độ chính
- 2. Chạy RSpec ở chế độ gỡ lỗi
- 3. có thể chạy chrome ở chế độ gỡ lỗi không?
- 4. Ống Django bị hỏng ở chế độ Gỡ lỗi
- 5. Gỡ lỗi trong .NET ở chế độ Release
- 6. độ chính xác chiều sâu opencv độ chính xác
- 7. iphone - NSTimers ở chế độ nền
- 8. Bàn phím mở ở chế độ toàn màn hình ở chế độ ngang
- 9. Bật chế độ linum khi ở chế độ python/c
- 10. Chế độ Viper ở tất cả các chế độ
- 11. Chế độ xem chia nhỏ ở chế độ dọc!
- 12. ngày chế độ org ở các chế độ Emacs khác
- 13. Độ chính xác độ cao CLLocation
- 14. Chạy chế độ quirks trong một chế độ khung và chế độ chuẩn ở chế độ khác?
- 15. Powershell ở chế độ NonInteractive
- 16. Cách chính xác cho máy chủ thăm dò ý kiến ở chế độ nền
- 17. Emacs C++ - chế độ thụt lề không chính xác?
- 18. Độ chính xác ngày giờ?
- 19. Thêm chế độ xem ở cuối Webview
- 20. Độ chính xác của Cython
- 21. Tọa độ GPS chính xác
- 22. Độ chính xác trong python
- 23. Tạo chế độ xem bằng khóa chính?
- 24. Vẽ trên chế độ xem có thể thu phóng
- 25. AVVideoCompositionCoreAnimationTool và CALayer ở chế độ dọc?
- 26. Cách chính xác để animate Chế độ xem từ một tọa độ này sang tọa độ khác là gì?
- 27. Chế độ gỡ lỗi và gỡ lỗi trong IDE
- 28. MediaRecorder quay video ở chế độ dọc
- 29. Độ chính xác của CLLocation chính xác đến mức nào?
- 30. Pinch Phóng to trong chế độ xem web [Android]
Tại sao bạn cho rằng chúng khác nhau? –
Vâng, tôi cũng muốn tìm hiểu quy trình suy nghĩ của bạn. –
Câu hỏi đặt ra là về sự khác biệt giữa gỡ lỗi và phát hành. Bạn sẽ nghĩ rằng phiên bản phát hành có thể sử dụng các thanh ghi thay vì RAM sẽ có độ chính xác cao hơn: FPU = 80bit, double = 64bit, float = 32bit. – Skizz