MATLAB で独自の SHA1 実装を作成しましたが、正しいハッシュが得られます。しかし、それは非常に遅いです (a
私の Core i7-2760QM では 1000 の文字列は 9.9 秒かかります)。その遅さは、MATLAB がビットごとの論理演算 ( bitand
、bitor
、bitxor
、bitcmp
) とビットごとのシフト ( bitshift
、bitrol
、bitror
)を実装する方法の結果だと思います。整数の。
特に、Intel x86アセンブリにはすべてのサイズのレジスタとメモリアドレスの両方があるため、コマンド用およびbitrol
使用bitror
用の固定小数点数値オブジェクトを作成する必要があるのではないかと思います。ただし、は非常に高速です (固定小数点数値構造体は必要ありません。通常の変数は正常に機能します)。これにより、状況が奇妙になります。アセンブリ レベルでは、 、、および?fi
rol
ror
bitshift
uint64
bitrol
bitror
fi
bitshift
shl
shr
rol
ror
したがって、この関数を C/C++ で .mex ファイルとして記述する前に、この関数のパフォーマンスを向上させる方法があれば教えていただければ幸いです。SHA1 にはいくつかの特定の最適化があることは知っていますが、ビットごとのローテーションの非常に基本的な実装が非常に遅い場合、それは問題ではありません。
tic
andで少しテストすると、遅くなっているのは withとtoc
のループであることは明らかです。このようなループが 2 つあります。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 秒が 2 番目の低速ループで渡されます。.mex ファイルを書き込む前に、MATLAB でこれらのループを最適化する方法はありますか?