提交 3a9b3852 编写于 作者: A Andy Polyakov

sha256-586.pl: squeeze some more, most notably ~10% on Nehalem.

上级 d2e18031
...@@ -17,18 +17,18 @@ ...@@ -17,18 +17,18 @@
# #
# Optimization including two of Pavel Semjanov's ideas, alternative # Optimization including two of Pavel Semjanov's ideas, alternative
# Maj and full unroll, resulted in ~20-25% improvement on most CPUs, # Maj and full unroll, resulted in ~20-25% improvement on most CPUs,
# ~10% on Pentium and P4, ~37% on Atom. As fully unrolled loop body is # ~7% on Pentium, ~40% on Atom. As fully unrolled loop body is almost
# almost 15x larger, 8KB vs. 560B, it's fired only for longer inputs. # 15x larger, 8KB vs. 560B, it's fired only for longer inputs. But not
# But not on P4, where it kills performance, nor Sandy Bridge, where # on P4, where it kills performance, nor Sandy Bridge, where folded
# folded loop is just as fast... # loop is approximately as fast...
# #
# Performance in clock cycles per processed byte (less is better): # Performance in clock cycles per processed byte (less is better):
# #
# Pentium PIII P4 AMD K8 Core2 SB(**) Atom # PIII P4 AMD K8 Core2 SB(**) Atom Bldzr
# gcc 46 36 41 27 26 25 50 # gcc 36 41 27 26 25 50 36
# icc 57 33 38 25 23 - - # icc 33 38 25 23 - - -
# x86 asm(*) 39/36 27/24 30 19/15.5 18/16 16(**) 30/26 # x86 asm(*) 27/24 28 19/15.5 18/15.6 16(**) 30/25 27/22
# x86_64 asm(***) - 17.5 15 16 17.5 23 # x86_64 asm(***) 17.5 15 15.5 17.5 23 21
# #
# (*) numbers after slash are for unrolled loop, where available; # (*) numbers after slash are for unrolled loop, where available;
# (**) for Sandy Bridge executing code path with ror replaced with # (**) for Sandy Bridge executing code path with ror replaced with
...@@ -42,7 +42,13 @@ require "x86asm.pl"; ...@@ -42,7 +42,13 @@ require "x86asm.pl";
&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386"); &asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
$unroll_after = 1024; $unroll_after = 64*4; # If pre-evicted from L1P cache first spin of
# fully unrolled loop was measured to run about
# 3-4x slower. If slowdown coefficient is N and
# unrolled loop is m times faster, then you break
# even at (N-1)/(m-1) blocks. Then it needs to be
# adjusted for probability of code being evicted,
# code size/cache size=1/4. Typical m is 1.15...
$A="eax"; $A="eax";
$E="edx"; $E="edx";
...@@ -65,9 +71,9 @@ sub BODY_16_63() { ...@@ -65,9 +71,9 @@ sub BODY_16_63() {
&mov ("edi","esi"); &mov ("edi","esi");
&ror ("esi",19-17); &ror ("esi",19-17);
&xor ("ecx",$T); &xor ("ecx",$T);
&shr ($T,3); &shr ($T,3);
&xor ("esi","edi");
&ror ("ecx",7); &ror ("ecx",7);
&xor ("esi","edi");
&xor ($T,"ecx"); # T = sigma0(X[-15]) &xor ($T,"ecx"); # T = sigma0(X[-15])
&ror ("esi",17); &ror ("esi",17);
&add ($T,&DWP(4*(9+15+16),"esp")); # T += X[-16] &add ($T,&DWP(4*(9+15+16),"esp")); # T += X[-16]
...@@ -96,8 +102,8 @@ sub BODY_00_15() { ...@@ -96,8 +102,8 @@ sub BODY_00_15() {
&and ("esi",$E); &and ("esi",$E);
&mov ($Eoff,$E); # modulo-scheduled &mov ($Eoff,$E); # modulo-scheduled
&xor ($E,"ecx"); &xor ($E,"ecx");
&xor ("esi","edi"); # Ch(e,f,g)
&add ($T,$Hoff); # T += h &add ($T,$Hoff); # T += h
&xor ("esi","edi"); # Ch(e,f,g)
&ror ($E,6); # Sigma1(e) &ror ($E,6); # Sigma1(e)
&mov ("ecx",$A); &mov ("ecx",$A);
&add ($T,"esi"); # T += Ch(e,f,g) &add ($T,"esi"); # T += Ch(e,f,g)
...@@ -162,7 +168,7 @@ sub BODY_00_15() { ...@@ -162,7 +168,7 @@ sub BODY_00_15() {
if ($unroll_after) { if ($unroll_after) {
&sub ("eax","edi"); &sub ("eax","edi");
&cmp ("eax",$unroll_after); &cmp ("eax",$unroll_after);
&jge (&label("unrolled")); &jae (&label("unrolled"));
} } } }
&jmp (&label("loop")); &jmp (&label("loop"));
...@@ -288,6 +294,7 @@ my $suffix=shift; ...@@ -288,6 +294,7 @@ my $suffix=shift;
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 ); 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 );
&data_word(@K256); &data_word(@K256);
&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f);
if (!$i386 && $unroll_after) { if (!$i386 && $unroll_after) {
my @AH=($A,$K256); my @AH=($A,$K256);
...@@ -333,70 +340,72 @@ my @AH=($A,$K256); ...@@ -333,70 +340,72 @@ my @AH=($A,$K256);
&mov (&DWP(96+4,"esp"),"edi"); &mov (&DWP(96+4,"esp"),"edi");
&mov (&DWP(32+12*$i,"esp"),"ebx"); &mov (&DWP(32+12*$i,"esp"),"ebx");
my ($t1,$t2) = ("ecx","esi");
my ($a,$b,$c,$d,$e,$f,$g,$h)=(0..7); # offsets my ($a,$b,$c,$d,$e,$f,$g,$h)=(0..7); # offsets
sub off { &DWP(4*(((shift)-$i)&7),"esp"); } sub off { &DWP(4*(((shift)-$i)&7),"esp"); }
for ($i=0;$i<64;$i++) { for ($i=0;$i<64;$i++) {
if ($i>=16) { if ($i>=16) {
&mov ($T,"ecx"); # "ecx" is preloaded &mov ($T,$t1); # $t1 is preloaded
# &mov ("esi",&DWP(32+4*(($i+14)&15),"esp")); # &mov ($t2,&DWP(32+4*(($i+14)&15),"esp"));
&ror ("ecx",18-7); &ror ($t1,18-7);
&mov ("edi","esi"); &mov ("edi",$t2);
&ror ("esi",19-17); &ror ($t2,19-17);
&xor ("ecx",$T); &xor ($t1,$T);
&shr ($T,3); &shr ($T,3);
&xor ("esi","edi"); &ror ($t1,7);
&ror ("ecx",7); &xor ($t2,"edi");
&xor ($T,"ecx"); # T = sigma0(X[-15]) &xor ($T,$t1); # T = sigma0(X[-15])
&ror ("esi",17); &ror ($t2,17);
&add ($T,&DWP(32+4*($i&15),"esp")); # T += X[-16] &add ($T,&DWP(32+4*($i&15),"esp")); # T += X[-16]
&shr ("edi",10); &shr ("edi",10);
&add ($T,&DWP(32+4*(($i+9)&15),"esp")); # T += X[-7] &add ($T,&DWP(32+4*(($i+9)&15),"esp")); # T += X[-7]
#&xor ("edi","esi") # sigma1(X[-2]) #&xor ("edi",$t2) # sigma1(X[-2])
# &add ($T,"edi"); # T += sigma1(X[-2]) # &add ($T,"edi"); # T += sigma1(X[-2])
# &mov (&DWP(4*(9+15),"esp"),$T); # save X[0] # &mov (&DWP(4*(9+15),"esp"),$T); # save X[0]
} }
&mov ("ecx",$E); &mov ($t1,$E);
&xor ("edi","esi") if ($i>=16); # sigma1(X[-2]) &xor ("edi",$t2) if ($i>=16); # sigma1(X[-2])
&mov ("esi",&off($f)); &mov ($t2,&off($f));
&ror ("ecx",25-11); &ror ($E,25-11);
&add ($T,"edi") if ($i>=16); # T += sigma1(X[-2]) &add ($T,"edi") if ($i>=16); # T += sigma1(X[-2])
&mov ("edi",&off($g)); &mov ("edi",&off($g));
&xor ("ecx",$E); &xor ($E,$t1);
&xor ("esi","edi");
&mov ($T,&DWP(32+4*($i&15),"esp")) if ($i<16); # X[i] &mov ($T,&DWP(32+4*($i&15),"esp")) if ($i<16); # X[i]
&mov (&DWP(32+4*($i&15),"esp"),$T) if ($i>=16); # save X[0] &mov (&DWP(32+4*($i&15),"esp"),$T) if ($i>=16 && $i<62); # save X[0]
&ror ("ecx",11-6); &xor ($t2,"edi");
&and ("esi",$E); &ror ($E,11-6);
&mov (&off($e),$E); # modulo-scheduled &and ($t2,$t1);
&xor ($E,"ecx"); &mov (&off($e),$t1); # save $E, modulo-scheduled
&xor ("esi","edi"); # Ch(e,f,g) &xor ($E,$t1);
&add ($T,&off($h)); # T += h &add ($T,&off($h)); # T += h
&xor ("edi",$t2); # Ch(e,f,g)
&ror ($E,6); # Sigma1(e) &ror ($E,6); # Sigma1(e)
&mov ("ecx",$AH[0]); &mov ($t1,$AH[0]);
&add ($T,"esi"); # T += Ch(e,f,g) &add ($T,"edi"); # T += Ch(e,f,g)
&ror ("ecx",22-13); &ror ($t1,22-13);
&mov ($t2,$AH[0]);
&mov ("edi",&off($b)); &mov ("edi",&off($b));
&xor ("ecx",$AH[0]); &xor ($t1,$AH[0]);
&mov (&off($a),$AH[0]); # modulo-scheduled &mov (&off($a),$AH[0]); # save $A, modulo-scheduled
&ror ("ecx",13-2);
&lea ($T,&DWP(@K256[$i],$T,$E)); # T += Sigma1(1)+K[i]
&mov ($E,&off($d)); # e in next iteration, d in this one
&xor ("ecx",$AH[0]);
&xor ($AH[0],"edi"); # a ^= b, (b^c) in next round &xor ($AH[0],"edi"); # a ^= b, (b^c) in next round
&ror ("ecx",2); # Sigma0(a) &ror ($t1,13-2);
&and ($AH[1],$AH[0]); # (b^c) &= (a^b)
&add ($E,$T); # d += T &lea ($E,&DWP(@K256[$i],$T,$E)); # T += Sigma1(1)+K[i]
&and ($AH[1],$AH[0]); # a &= (b^c) &xor ($t1,$t2);
&add ($T,"ecx"); # T += Sigma0(a) &xor ($AH[1],"edi"); # h = Maj(a,b,c) = Ch(a^b,c,b)
&mov ("ecx",&DWP(32+4*(($i+2)&15),"esp")) if ($i>=15 && $i<63); &mov ($t2,&DWP(32+4*(($i+2)&15),"esp")) if ($i>=15 && $i<63);
&xor ($AH[1],"edi"); # h = Maj(a,b,c) = Ch(a^b,c,b) &ror ($t1,2); # Sigma0(a)
&mov ("esi",&DWP(32+4*(($i+15)&15),"esp")) if ($i>=15 && $i<63);
&add ($AH[1],$T); # h += T &add ($AH[1],$E); # h += T
&add ($E,&off($d)); # d += T
unshift(@AH,pop(@AH)); # rotate(a,h) &add ($AH[1],$t1); # h += Sigma0(a)
&mov ($t1,&DWP(32+4*(($i+15)&15),"esp")) if ($i>=15 && $i<63);
@AH = reverse(@AH); # rotate(a,h)
($t1,$t2) = ($t2,$t1); # rotate(t1,t2)
} }
&mov ("esi",&DWP(96,"esp")); #ctx &mov ("esi",&DWP(96,"esp")); #ctx
#&mov ($AH[0],&DWP(0,"esp")); #&mov ($AH[0],&DWP(0,"esp"));
......
...@@ -106,20 +106,20 @@ $code.=<<___; ...@@ -106,20 +106,20 @@ $code.=<<___;
xor $e,$a0 xor $e,$a0
xor $g,$a2 # f^g xor $g,$a2 # f^g
ror \$`$Sigma1[1]-$Sigma1[0]`,$a0 mov $T1,`$SZ*($i&0xf)`(%rsp)
xor $a,$a1 xor $a,$a1
and $e,$a2 # (f^g)&e and $e,$a2 # (f^g)&e
mov $T1,`$SZ*($i&0xf)`(%rsp) ror \$`$Sigma1[1]-$Sigma1[0]`,$a0
add $h,$T1 # T1+=h add $h,$T1 # T1+=h
xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g
ror \$`$Sigma0[1]-$Sigma0[0]`,$a1 ror \$`$Sigma0[1]-$Sigma0[0]`,$a1
add $a2,$T1 # T1+=Ch(e,f,g)
xor $e,$a0 xor $e,$a0
add $a2,$T1 # T1+=Ch(e,f,g)
add ($Tbl),$T1 # T1+=K[round]
mov $a,$a2 mov $a,$a2
add ($Tbl),$T1 # T1+=K[round]
xor $a,$a1 xor $a,$a1
ror \$$Sigma1[0],$a0 # Sigma1(e) ror \$$Sigma1[0],$a0 # Sigma1(e)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册