【发布时间】:2012-07-14 09:15:40
【问题描述】:
我在 MATLAB 中编写了自己的 SHA1 实现,它提供了正确的哈希值。但是,它非常慢(在我的 Core i7-2760QM 上,一个 1000 a 的字符串需要 9.9 秒),我认为缓慢是 MATLAB 如何实现按位逻辑运算的结果(bitand,bitor, bitxor、bitcmp)和整数的按位移位(bitshift、bitrol、bitror)。
我特别想知道是否需要使用fi 命令为bitrol 和bitror 构造定点数字对象,因为无论如何在英特尔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 进行测量,消息abc 的 SHA1 哈希的整个计算在我的笔记本电脑上花费了大约 0.63 秒,其中大约 0.23 秒在第一个慢循环中传递,大约 0.38 秒在第二个慢循环。那么在编写 .mex 文件之前,有没有办法在 MATLAB 中优化这些循环?
【问题讨论】:
标签: performance matlab integer bit-manipulation