Đây là mã có thêm hai gấp ba của Words không có hộp bọc đại diện cho một số 192 bit thành một triple mới của Words không có hộp bọc, và cũng có thể trả về bất kỳ tràn:Bắt GHC để sản xuất "Thêm Với Carry (ADC)" hướng dẫn
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
import GHC.Prim(plusWord2#, Word#, or#)
longAdd ::
(# Word#, Word#, Word# #) ->
(# Word#, Word#, Word# #) ->
(# Word#, (# Word#, Word#, Word# #) #)
longAdd (# xl, xm, xh #) (# yl, ym, yh #) =
let
plusWord3 x y c =
let
(# c1, r1 #) = plusWord2# x y
(# c2, r2 #) = plusWord2# r1 c
in
(# plusWord# c1 c2, r2 #)
(# cl, rl #) = plusWord2# xl yl
(# cm, rm #) = plusWord3 xm ym cl
(# ch, rh #) = plusWord3 xh yh cm
in
(# ch, (# rl, rm, rh #) #)
Vấn đề là định nghĩa "plusWord3". Lý tưởng nhất, điều này cũng giống như một chức năng "ADC", trong đó có hai từ và các bit thực hiện và trả về kết quả và một carry mới, vì vậy việc lắp ráp kết quả là như sau:
add x1 y1
adc x2 y2
adc x3 y3
Thật không may GHC, cho dù mẹ đẻ hoặc thông qua LLVM, tạo mã lắp ráp xấu xí có liên quan đến việc lưu bit mang vào sổ đăng ký và sau đó đọc nó qua một phần bổ sung riêng biệt, thay vì chỉ sử dụng adc
. Tôi không muốn gọi một hàm C bên ngoài để đạt được điều này, khi một khi bạn thêm phí gọi, nó có thể không đáng, tôi muốn ở lại Haskell để mã có thể được inline nếu có thể. Nhưng tôi cũng muốn để có thể dỗ các trình biên dịch vào sản xuất các hướng dẫn adc
một cách thích hợp. Có anyway tôi có thể đạt được điều đó?
192 bit từ (và nhiều từ khác) có sẵn trong ['Dữ liệu.DoubleWord'] (https://hackage.haskell.org/package/data-dword-0.3/docs/Data-DoubleWord.html). Tôi tự hỏi nếu nó được tối ưu hóa để tạo ra mã hiệu quả, vì vậy nó có thể là một nguồn kiến thức làm thế nào để làm điều đó, hoặc một nơi để đóng góp, một khi bạn tìm thấy câu trả lời. –