Các triển khai BLAS có được đảm bảo để đưa ra kết quả chính xác không?


17

Đưa ra hai cách triển khai BLAS khác nhau, chúng ta có thể hy vọng rằng chúng thực hiện các phép tính điểm chính xác giống nhau và trả về cùng kết quả không? Hoặc nó có thể xảy ra, ví dụ, rằng một tính một sản phẩm vô hướng như và một như để có thể đưa ra kết quả khác nhau trong IEEE dấu chấm động Môn số học?

((x1y1+x2y2)+x3y3)+x4y4
(x1y1+x2y2)+(x3y3+x4y4),

1
Có một số khiếu nại về chất lượng BLAS trong chủ đề này , tìm kiếm CBLAS trong trang. Điều đó sẽ gợi ý rằng không chỉ họ không cho kết quả tương tự, mà không phải tất cả chúng đều đủ chính xác cho bất kỳ nhiệm vụ nào ...
Szabolcs

Câu trả lời:


15

Không, điều đó không được đảm bảo. Nếu bạn đang sử dụng NETLIB BLAS mà không có bất kỳ tối ưu hóa nào, thì hầu như đúng là các kết quả đều giống nhau. Nhưng đối với bất kỳ việc sử dụng thực tế nào của BLAS và LAPACK, người ta sử dụng BLAS song song được tối ưu hóa cao. Sự song song gây ra, ngay cả khi nó chỉ hoạt động song song bên trong các thanh ghi vectơ của CPU, theo thứ tự các thuật ngữ đơn được đánh giá thay đổi và thứ tự tổng kết cũng thay đổi. Bây giờ nó theo mẫu thuộc tính kết hợp bị thiếu trong tiêu chuẩn IEEE rằng các kết quả không giống nhau. Vì vậy, chính xác những điều bạn đề cập có thể xảy ra.

Trong NETLIB BLAS, sản phẩm vô hướng chỉ là một vòng lặp for không được kiểm soát bởi yếu tố 5:

DO I = MP1,N,5
          DTEMP = DTEMP + DX(I)*DY(I) + DX(I+1)*DY(I+1) +
     $            DX(I+2)*DY(I+2) + DX(I+3)*DY(I+3) + DX(I+4)*DY(I+4)
END DO

và tùy thuộc vào trình biên dịch nếu mỗi phép nhân được thêm vào DTEMP ngay lập tức hoặc nếu tất cả 5 thành phần được tóm tắt trước và được thêm vào DTEMP. Trong OpenBLAS, tùy thuộc vào kiến ​​trúc, hạt nhân phức tạp hơn:

 __asm__  __volatile__
    (
    "vxorpd     %%ymm4, %%ymm4, %%ymm4               \n\t"
    "vxorpd     %%ymm5, %%ymm5, %%ymm5               \n\t"
    "vxorpd     %%ymm6, %%ymm6, %%ymm6               \n\t"
    "vxorpd     %%ymm7, %%ymm7, %%ymm7               \n\t"

    ".align 16                           \n\t"
    "1:                          \n\t"
        "vmovups                  (%2,%0,8), %%ymm12         \n\t"  // 2 * x
        "vmovups                32(%2,%0,8), %%ymm13         \n\t"  // 2 * x
        "vmovups                64(%2,%0,8), %%ymm14         \n\t"  // 2 * x
        "vmovups                96(%2,%0,8), %%ymm15         \n\t"  // 2 * x

    "vmulpd      (%3,%0,8), %%ymm12, %%ymm12 \n\t"  // 2 * y
    "vmulpd    32(%3,%0,8), %%ymm13, %%ymm13 \n\t"  // 2 * y
    "vmulpd    64(%3,%0,8), %%ymm14, %%ymm14 \n\t"  // 2 * y
    "vmulpd    96(%3,%0,8), %%ymm15, %%ymm15 \n\t"  // 2 * y

    "vaddpd      %%ymm4 , %%ymm12, %%ymm4 \n\t"  // 2 * y
    "vaddpd      %%ymm5 , %%ymm13, %%ymm5 \n\t"  // 2 * y
    "vaddpd      %%ymm6 , %%ymm14, %%ymm6 \n\t"  // 2 * y
    "vaddpd      %%ymm7 , %%ymm15, %%ymm7 \n\t"  // 2 * y

    "addq       $16 , %0	  	     \n\t"
	"subq	        $16 , %1            \n\t"      
    "jnz        1b                   \n\t"
...

trong đó phân tách sản phẩm vô hướng trong các sản phẩm vô hướng nhỏ có chiều dài 4 và tổng hợp chúng lại.

Sử dụng các triển khai BLAS điển hình khác như ATLAS, MKL, ESSL, ... vấn đề này vẫn giữ nguyên vì mỗi triển khai BLAS sử dụng các tối ưu hóa khác nhau để có được mã nhanh. Nhưng theo tôi biết người ta cần một ví dụ nhân tạo để gây ra kết quả thực sự bị lỗi.

Nếu cần thư viện BLAS trả về cho cùng một kết quả (bit-khôn giống nhau), người ta phải sử dụng thư viện BLAS có thể sao chép, chẳng hạn như:


8

Câu trả lời ngắn

Nếu hai triển khai BLAS được viết để thực hiện các hoạt động theo cùng một thứ tự chính xác và các thư viện được biên dịch bằng các cờ trình biên dịch giống nhau và với cùng một trình biên dịch, thì chúng sẽ cho bạn kết quả tương tự. Số học dấu phẩy động không phải là ngẫu nhiên, vì vậy hai triển khai giống hệt nhau sẽ cho kết quả giống hệt nhau.

Tuy nhiên, có nhiều thứ có thể phá vỡ hành vi này vì mục đích thực hiện ...

Câu trả lời dài hơn

IEEE cũng chỉ định thứ tự thực hiện các thao tác này, ngoài cách thức hoạt động của từng hoạt động. Tuy nhiên, nếu bạn biên dịch triển khai BLAS của mình với các tùy chọn như "-ffast-math", trình biên dịch có thể thực hiện các phép biến đổi đúng với số học chính xác nhưng không "chính xác" trong dấu phẩy động của IEEE. Ví dụ kinh điển là tính không kết hợp của phép cộng dấu phẩy động, như bạn đã chỉ ra. Với các cài đặt tối ưu hóa mạnh mẽ hơn, tính kết hợp sẽ được giả định và bộ xử lý sẽ thực hiện càng nhiều điều đó càng tốt bằng cách sắp xếp lại các thao tác.

một+b*c


3
"Số học dấu phẩy động không phải là ngẫu nhiên" . Thật đáng buồn khi điều này phải được tuyên bố rõ ràng, nhưng dường như có quá nhiều người nghĩ rằng đó là ...
đường ống

Chà, trông không thể đoán trước và ngẫu nhiên trông khá giống nhau, và rất nhiều lớp lập trình giới thiệu nói rằng "không bao giờ so sánh số float cho đẳng thức", điều này tạo ấn tượng rằng giá trị chính xác không thể dựa vào giống như số nguyên.
Tyler Olsen

@TylerOlsen Điều này không liên quan đến câu hỏi và đây không phải là lý do tại sao các lớp đó nói những điều như vậy, nhưng IIRC, đã từng có một lớp lỗi trình biên dịch mà sự bình đẳng không thể dựa vào. Ví dụ, đôi khi if (x == 0) assert(x == 0) có thể thất bại, mà từ một quan điểm nhất định là tốt như ngẫu nhiên.
Kirill

@Kirill Xin lỗi, tôi chỉ đơn giản là cố gắng đưa ra quan điểm rằng nhiều người không bao giờ thực sự tìm hiểu cách hoạt động của dấu phẩy động. Về điểm lịch sử, điều đó thật đáng sợ, nhưng nó phải được giải quyết trước khi tôi vào trò chơi.
Tyler Olsen

@TylerOlsen Rất tiếc, ví dụ của tôi là sai. Nó nên if (x != 0) assert(x != 0), bởi vì số học chính xác mở rộng.
Kirill

4

Nói chung, không. Bỏ tính kết hợp sang một bên, việc lựa chọn cờ trình biên dịch (ví dụ: hướng dẫn SIMD được bật, sử dụng phép cộng bội , v.v.) hoặc phần cứng (ví dụ: có sử dụng độ chính xác mở rộng hay không ) có thể tạo ra các kết quả khác nhau.

Có một số nỗ lực để có được các triển khai BLAS có thể tái tạo. Xem ReproBLASExBLAS để biết thêm thông tin.


1
Xem thêm tính năng Tái sản xuất số có điều kiện (CNR) trong các phiên bản gần đây của MKL BLAS của Intel. Nhận ra rằng việc đạt được mức độ tái tạo này thường sẽ làm chậm quá trình tính toán của bạn và có thể làm chậm chúng đi rất nhiều!
Brian Borchers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.