6

Tôi muốn biên dịch một mô-đun Mathematica vì tôi sau tốc độ.Mathematica - Cách biên dịch BitShiftRight (hoặc Trái)?

testC = Compile[{{inputInt, _Integer}}, 
     Module[{outputInt, bitShift = 5}, 
     outputInt = BitShiftRight[inputInt, bitShift] 
     ] 
     , CompilationTarget -> "C", RuntimeOptions -> "Speed" 
     , CompilationOptions -> {"ExpressionOptimization" -> True, 
     "InlineCompiledFunctions" -> True, 
     "InlineExternalDefinitions" -> True} 
    ]; 

Chức năng thực của tôi dài hơn nhưng có cấu trúc rất đơn giản, sử dụng danh sách và chỉ chứa hàm sau: Tổng, Bảng, Bit và, Nếu. Tất cả các tùy chọn biên dịch và thời gian chạy là hữu ích (có thể) trong hàm thực của tôi, không phải là giải nén một dòng này.

tôi đã thiết

SetSystemOptions [ "CompileOptions" -> "CompileReportExternal" -> Đúng];

để chắc chắn rằng tôi có thể xem những gì sẽ xảy ra, và

CompilePrint [testC]

cho kết quả sau

1 argument 
    3 Integer registers 
Underflow checking off 
Overflow checking off 
Integer overflow checking off 
RuntimeAttributes -> {} 

    I0 = A1 
    I1 = 5 
    Result = I2 

    1 I2 = MainEvaluate[ Hold[BitShiftRight][ I0, I1]] 
    2 Return 

Đúng như dự đoán/sợ từ chủ đề này https://mathematica.stackexchange.com/a/1101/1403 BitShiftRight không thể đồng bộ hóa và cuộc gọi này tới MainEvaluate là một sự kéo dài nghiêm trọng trên dấu chấm câu của tôi ion. Tôi cực kỳ ngạc nhiên khi mức độ này rất thấp, chức năng chung không phải là compilable trong khi BitAnd, BitNot, BitOr, BitXor! Có ai biết cách giải quyết nhanh không? Tôi có thể sử dụng một cuộc gọi MathLink đến một hàm ngôn ngữ C, nhưng mục tiêu của tôi là sử dụng hàm này trong một Thao tác [] và triển khai nó như một tệp cdf độc lập. Và tôi hiểu rằng trong bối cảnh này tôi không thể sử dụng MathLink, đúng không? Nhân tiện, có một số cách giải quyết có thể xử lý được không?

Trả lời

3

Nếu bạn chia cho 32, trình biên dịch có thể sẽ viết lại điều này dưới dạng ca làm việc. Bạn cũng nên thử chia cho 32 trong Mathematica trực tiếp, đảm bảo dữ liệu của bạn và vẫn được đóng gói (Developer`ToPackedArray []). Chi phí cho việc gửi dữ liệu qua lại có thể sẽ không xứng đáng với lợi ích của việc tính toán trong C.

+0

Chỉ cần xác nhận (và hơi sửa đổi), nếu bạn sử dụng Quotient, nó sẽ biên dịch các cuộc gọi đánh giá bên ngoài. Trong ví dụ đơn giản, dòng thích hợp sẽ là outputInt = Quotient [inputInt, 2^bitShift]]. Nếu độ dài thay đổi của bạn là một hằng số cố định, việc cấp nguồn phải được thực hiện tại thời gian biên dịch (có thể cả hai đều biết rằng ...). –

+0

@Daniel: Giải pháp của bạn giải quyết pb của tôi. Cám ơn! Sau đó, mã được biên dịch là 'I3 = Quotient [I0, I2]'. Nếu tôi chỉ chia cho 2^5, tôi cần phải làm tròn [] kết quả để đúc nó thành một số nguyên. Sau đó, mã biên dịch là 'R1 = đối ứng [R0] ' 'R0 = I0'' R0 = R0 * R1' 'I3 = Vòng [R0]' (dài hơn, kém hiệu quả hơn). – Oscar6E

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