我已經寫在MATLAB我自己的SHA1的實現,它給正確的哈希值。然而,它非常慢(我的Core i7-2760QM上的字符串1000 a
需要9.9秒),我認爲這種慢度是由MATLAB如何實現按位邏輯運算(bitand
,bitor
,,bitcmp
)和按位整數的位移(bitshift
,bitrol
,bitror
)。如何優化MATLAB位操作
尤其是我不知道需要建造定點數值對象爲bitrol
和bitror
使用fi
命令,因爲反正在英特爾x86彙編有rol
和ror
既爲各種規模的寄存器和存儲器地址。然而,bitshift
速度相當快(它不需要任何定點數字結構,常規uint64
變量工作正常),這使情況變得陌生:爲什麼在MATLAB bitrol
和bitror
需要使用fi
構建的定點數字對象,而bitshift
不,當裝配水平都歸結到shl
,shr
,rol
和ror
?
因此,在C/C寫這個函數++作爲.mex文件之前,我很樂意知道是否有什麼辦法改善這種功能的性能。我知道對SHA1有一些特定的優化,但如果按位旋轉的基本實現非常慢,那不是問題。
測試一點點與tic
和toc
,這是顯而易見的是什麼使得它慢是與bitrol
和fi
環。有兩個這樣的循環:
%# Define some variables.
FFFFFFFF = uint64(hex2dec('FFFFFFFF'));
%# constants: K(1), K(2), K(3), K(4).
K(1) = uint64(hex2dec('5A827999'));
K(2) = uint64(hex2dec('6ED9EBA1'));
K(3) = uint64(hex2dec('8F1BBCDC'));
K(4) = uint64(hex2dec('CA62C1D6'));
W = uint64(zeros(1, 80));
... some other code here ...
%# First slow loop begins here.
for index = 17:80
W(index) = uint64(bitrol(fi(bitxor(bitxor(bitxor(W(index-3), W(index-8)), W(index-14)), W(index-16)), 0, 32, 0), 1));
end
%# First slow loop ends here.
H = sha1_handle_block_struct.H;
A = H(1);
B = H(2);
C = H(3);
D = H(4);
E = H(5);
%# Second slow loop begins here.
for index = 1:80
rotatedA = uint64(bitrol(fi(A, 0, 32, 0), 5));
if (index <= 20)
% alternative #1.
xorPart = bitxor(D, (bitand(B, (bitxor(C, D)))));
xorPart = bitand(xorPart, FFFFFFFF);
temp = rotatedA + xorPart + E + W(index) + K(1);
elseif ((index >= 21) && (index <= 40))
% FIPS.
xorPart = bitxor(bitxor(B, C), D);
xorPart = bitand(xorPart, FFFFFFFF);
temp = rotatedA + xorPart + E + W(index) + K(2);
elseif ((index >= 41) && (index <= 60))
% alternative #2.
xorPart = bitor(bitand(B, C), bitand(D, bitxor(B, C)));
xorPart = bitand(xorPart, FFFFFFFF);
temp = rotatedA + xorPart + E + W(index) + K(3);
elseif ((index >= 61) && (index <= 80))
% FIPS.
xorPart = bitxor(bitxor(B, C), D);
xorPart = bitand(xorPart, FFFFFFFF);
temp = rotatedA + xorPart + E + W(index) + K(4);
else
error('error in the code of sha1_handle_block.m!');
end
temp = bitand(temp, FFFFFFFF);
E = D;
D = C;
C = uint64(bitrol(fi(B, 0, 32, 0), 30));
B = A;
A = temp;
end
%# Second slow loop ends here.
與tic
和toc
,消息的SHA1哈希整個計算abc
發生在我的筆記本電腦周圍0.63秒,其中約0.23秒在第一個慢環和周圍通過測量在第二個慢循環中爲0.38秒。那麼在編寫.mex文件之前,有什麼方法可以在MATLAB中優化這些循環?
在我看來,加速SHA1的選項是使用'java.security.MessageDigest'庫或編寫一個MEX函數。正如我打算讓我的MATLAB代碼與GNU Octave兼容(也希望將GNU Octave用作開發環境),並且似乎在處理Java和Octave之間存在一些差異,使用Java庫是一個非理想的解決方案。然而,'DataHash'非常快,因此在執行MEX解決方案之前就可以完成這項工作,或者找到另一種有效實現SHA1的方法,而無需使用Java。 – nrz 2012-07-15 11:00:03
將我自己的fMRI分析工具箱移植到Octave是我的一個長期項目,我不想基於此來限制答案。無論如何,我目前需要的是一種有效的方式來計算大型文件(在MATLAB中)的SHA1,以便能夠繼續開發,'DataHash'是一個可行的解決方案。 – nrz 2012-07-15 11:34:01
@nrz:Octave具有兼容的MEX API來編寫C擴展。他們也有自己的API來編寫OCT文件(相當於MATLAB中的MEX文件)。 – Amro 2012-07-15 11:45:58