2009-06-09 41 views
6

Đã đọc điều này question Tôi chắc chắn rằng một quy trình nhất định sử dụng dấu chấm động arithmatic với cùng một đầu vào (trên cùng một phần cứng, được biên dịch với cùng một trình biên dịch) xác định. Tôi đang xem xét một trường hợp điều này không đúng và cố gắng xác định điều gì có thể gây ra điều này.Điều gì có thể gây ra một quá trình xác định để tạo ra các lỗi dấu phẩy động

Tôi đã biên dịch một tệp thi hành và tôi đang cho nó cùng một dữ liệu, chạy trên một máy duy nhất (không đa luồng) nhưng tôi gặp lỗi khoảng 3.814697265625e-06 sau khi tìm kiếm cẩn thận thực sự bằng 1/4^9 = 1/2^18 = 1/262144. đó là khá gần với mức độ chính xác của một số điểm nổi 32-bit (khoảng 7 chữ số theo wikipedia)

Nghi ngờ của tôi là nó có liên quan đến việc tối ưu hóa đã được áp dụng cho mã. Tôi đang sử dụng trình biên dịch C++ intel và đã biến đầu cơ điểm nổi thành nhanh thay vì an toàn hoặc nghiêm ngặt. Điều này có thể làm cho một quá trình điểm nổi không xác định? Có những sự tối ưu hóa khác có thể dẫn đến hành vi này không?

EDIT: Theo đề xuất của Pax, tôi biên dịch lại mã với đầu cơ điểm động được chuyển sang an toàn và giờ đây tôi nhận được kết quả ổn định. Điều này cho phép tôi làm rõ câu hỏi này - điều đầu cơ nổi thực sự làm gì và làm sao điều này có thể gây ra cùng một nhị phân (tức là một trình biên dịch, nhiều lần chạy) để tạo ra các kết quả khác nhau khi được áp dụng cho cùng một đầu vào?

@Ben tôi đang biên soạn bằng Intel (R) C++ 11.0.061 [IA-32] và tôi đang chạy trên bộ xử lý lõi tứ của Intel.

+0

Bộ xử lý và trình biên dịch nào? .. xin vui lòng – Ben

+0

Nếu bạn đã tìm ra lá cờ nào đang gây ra nó, tại sao không chỉ kiểm tra tài liệu biên dịch? –

+0

@Tal - Tôi đang gặp khó khăn trong việc tìm ra bất cứ điều gì từ tài liệu (nó chỉ nói nhanh cho phép fps và an toàn/nghiêm ngặt vô hiệu hóa nó). Điều tốt nhất tôi có thể hiểu nó, fps cho phép sắp xếp lại các hoạt động (a * c + b * c => c * (a + b)) nhưng đây là những tối ưu hóa thời gian biên dịch, kết quả nhị phân vẫn phải xác định và tôi thực sự muốn để biết chính xác lý do tại sao nó không phải là. –

Trả lời

13

Trong hầu hết mọi trường hợp, ở đó có chế độ nhanh và chế độ an toàn, bạn sẽ thấy một sự cân bằng nào đó. Nếu không, mọi thứ sẽ chạy ở chế độ an toàn nhanh :-).

Và nếu bạn nhận được kết quả khác nhau với cùng một đầu vào, quá trình của bạn là không phải là xác định, bất kể bạn tin nó thế nào (mặc dù bằng chứng thực nghiệm).

Tôi cho rằng giải thích của bạn là rất có thể. Đặt nó trong chế độ an toàn và xem nếu quyết định không biến mất. Điều đó sẽ cho bạn biết chắc chắn.

Là để cho dù có tối ưu hóa khác, nếu bạn đang biên soạn trên cùng một phần cứng với trình biên dịch cùng/linker và các tùy chọn tương tự đối với những công cụ, cần tạo mã giống hệt nhau. Tôi không thể nhìn thấy bất kỳ khả năng nào khác ngoài chế độ nhanh (hoặc bit bị thối trong bộ nhớ do tia vũ trụ, nhưng đó là điều không chắc chắn).

Tiếp theo cập nhật của bạn:

Intel có một tài liệu here mà giải thích một số trong những điều họ không được phép làm trong chế độ an toàn, bao gồm nhưng không giới hạn:

  • reassociation: (a+b)+c -> a+(b+c).
  • không gấp: x + 0 -> x, x * 0 -> 0.
  • nhân đối ứng: a/b -> a*(1/b).

Trong khi bạn tuyên bố rằng các hoạt động này được xác định thời gian biên dịch, các chip Intel khá darned thông minh.Họ có thể sắp xếp lại các lệnh để giữ đường ống đầy trong các thiết lập nhiều CPU, trừ khi mã này nghiêm cấm hành vi đó, mọi thứ có thể thay đổi vào thời gian chạy (không biên dịch) để giữ cho mọi thứ diễn ra ở tốc độ tối đa.

này được bảo vệ (tóm tắt) trên trang 15 của tài liệu đó liên kết mà nói về vector hóa ("Vấn đề: kết quả khác nhau chạy lại nhị phân như nhau trên cùng một dữ liệu trên bộ vi xử lý tương tự").

Lời khuyên của tôi sẽ là quyết định xem bạn có cần grunt thô hoặc tổng khả năng tái tạo kết quả và sau đó chọn chế độ dựa trên đó.

+0

Cảm ơn lời giải thích và tài nguyên tốt. Tài liệu mà bạn đã liên kết không cho biết vấn đề này (nơi mà địa chỉ ngăn xếp toàn cục và sự liên kết có thể thay đổi do các sự kiện bên ngoài tiến trình đang chạy) đã được sửa trong chuỗi trình biên dịch intel 11.x (mà tôi đang sử dụng). Tuy nhiên tôi nghĩ rằng bạn có thể nhấn vào câu trả lời trong đó có một số loại lệnh sắp đặt lại xảy ra khi chạy với nhiều cpus và nhiều ứng dụng đang mở. Cảm ơn một lần nữa. –

0

Nếu chương trình của bạn được song song, vì nó có thể chạy trên lõi tứ, thì nó có thể không xác định được.

Hãy tưởng tượng rằng bạn có 4 bộ xử lý thêm một giá trị dấu phẩy động vào cùng một vị trí bộ nhớ. Sau đó, bạn có thể nhận được

(((InitialValue+P1fp)+P2fp)+P3fp)+P4fp 

hoặc

(((InitialValue+P2fp)+P3fp)+P1fp)+P4fp 

hoặc bất kỳ các orderings thể khác.

Heck, bạn thậm chí có thể nhận được

InitialValue+(P2fp+P3fp)+(P1fp+P4fp) 

nếu trình biên dịch là đủ tốt.

Thật không may, bổ sung dấu phẩy động không giao hoán hoặc liên kết. Số học số thực là, nhưng dấu phẩy động không phải là do làm tròn, tràn và tràn.

Do đó, tính toán FP song song thường không xác định. "Thông thường", bởi vì chương trình trông giống như

on each processor 
    while(there is work to do) { 
     get work 
     calculate result 
     add to total 
    } 

sẽ không xác định, bởi vì số lượng thời gian mà mỗi có thể rất khác nhau - bạn không thể dự đoán thứ tự của các hoạt động. (Tồi tệ hơn nếu các chủ đề tương tác.)

Nhưng không phải lúc nào, vì có các kiểu lập trình song song xác định.

Tất nhiên, những gì nhiều người quan tâm đến tính xác định làm là làm việc trong số nguyên hoặc điểm cố định để tránh vấn đề. Tôi đặc biệt thích superaccumulators, 512, 1024, hoặc 2048 bit số mà số điểm nổi có thể được thêm vào, mà không bị lỗi làm tròn.


Đối với một ứng dụng đơn luồng: trình biên dịch có thể sắp xếp lại mã. Các bộ sưu tập khác nhau có thể đưa ra các câu trả lời khác nhau. Nhưng bất kỳ nhị phân cụ thể nào đều phải xác định.

Trừ khi ... bạn đang làm việc bằng ngôn ngữ động. Điều đó thực hiện tối ưu hóa để sắp xếp lại các tính toán FP, thay đổi theo thời gian.

Hoặc trừ khi ... quay thực sự lâu: Itanium có một số tính năng, giống như ALAT, mà thậm chí tạo ra một chuỗi đơn không được xác định. Bạn không có khả năng bị ảnh hưởng bởi những điều này.

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