77
88namespace CryptoBase . Benchmark ;
99
10+ [ RankColumn ]
1011public class Xor16Benchmark
1112{
1213 private Memory < byte > _a ;
@@ -22,91 +23,70 @@ public void Setup()
2223 [ Benchmark ( Baseline = true , Description = @"Normal" ) ]
2324 public void A ( )
2425 {
25- Xor ( _a . Span , _b . Span ) ;
26+ Span < byte > a = _a . Span ;
27+ Span < byte > b = _b . Span ;
2628
27- return ;
28-
29- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
30- static void Xor ( Span < byte > a , Span < byte > b )
29+ for ( int i = 0 ; i < 16 ; ++ i )
3130 {
32- for ( int i = 0 ; i < 16 ; ++ i )
33- {
34- a [ i ] ^= b [ i ] ;
35- }
31+ a [ i ] ^= b [ i ] ;
3632 }
3733 }
3834
3935 [ Benchmark ( Description = @"Without bounds checking" ) ]
4036 public void B ( )
4137 {
42- Xor ( _a . Span , _b . Span ) ;
43-
44- return ;
38+ Span < byte > a = _a . Span ;
39+ Span < byte > b = _b . Span ;
4540
46- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
47- static void Xor ( Span < byte > a , Span < byte > b )
41+ for ( int i = 0 ; i < 16 ; ++ i )
4842 {
49- for ( int i = 0 ; i < 16 ; ++ i )
50- {
51- a . GetRef ( i ) ^ = b . GetRef ( i ) ;
52- }
43+ a . GetRef ( i ) ^ = b . GetRef ( i ) ;
5344 }
5445 }
5546
5647 [ Benchmark ( Description = @"Without bounds checking + unrolling" ) ]
5748 public void B2 ( )
5849 {
59- Xor ( _a . Span , _b . Span ) ;
60-
61- return ;
62-
63- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
64- static void Xor ( Span < byte > a , Span < byte > b )
65- {
66- a . GetRef ( 0 ) ^ = b . GetRef ( 0 ) ;
67- a . GetRef ( 1 ) ^ = b . GetRef ( 1 ) ;
68- a . GetRef ( 2 ) ^ = b . GetRef ( 2 ) ;
69- a . GetRef ( 3 ) ^ = b . GetRef ( 3 ) ;
70- a . GetRef ( 4 ) ^ = b . GetRef ( 4 ) ;
71- a . GetRef ( 5 ) ^ = b . GetRef ( 5 ) ;
72- a . GetRef ( 6 ) ^ = b . GetRef ( 6 ) ;
73- a . GetRef ( 7 ) ^ = b . GetRef ( 7 ) ;
74- a . GetRef ( 8 ) ^ = b . GetRef ( 8 ) ;
75- a . GetRef ( 9 ) ^ = b . GetRef ( 9 ) ;
76- a . GetRef ( 10 ) ^ = b . GetRef ( 10 ) ;
77- a . GetRef ( 11 ) ^ = b . GetRef ( 11 ) ;
78- a . GetRef ( 12 ) ^ = b . GetRef ( 12 ) ;
79- a . GetRef ( 13 ) ^ = b . GetRef ( 13 ) ;
80- a . GetRef ( 14 ) ^ = b . GetRef ( 14 ) ;
81- a . GetRef ( 15 ) ^ = b . GetRef ( 15 ) ;
82- }
50+ Span < byte > a = _a . Span ;
51+ Span < byte > b = _b . Span ;
52+
53+ a . GetRef ( 0 ) ^ = b . GetRef ( 0 ) ;
54+ a . GetRef ( 1 ) ^ = b . GetRef ( 1 ) ;
55+ a . GetRef ( 2 ) ^ = b . GetRef ( 2 ) ;
56+ a . GetRef ( 3 ) ^ = b . GetRef ( 3 ) ;
57+ a . GetRef ( 4 ) ^ = b . GetRef ( 4 ) ;
58+ a . GetRef ( 5 ) ^ = b . GetRef ( 5 ) ;
59+ a . GetRef ( 6 ) ^ = b . GetRef ( 6 ) ;
60+ a . GetRef ( 7 ) ^ = b . GetRef ( 7 ) ;
61+ a . GetRef ( 8 ) ^ = b . GetRef ( 8 ) ;
62+ a . GetRef ( 9 ) ^ = b . GetRef ( 9 ) ;
63+ a . GetRef ( 10 ) ^ = b . GetRef ( 10 ) ;
64+ a . GetRef ( 11 ) ^ = b . GetRef ( 11 ) ;
65+ a . GetRef ( 12 ) ^ = b . GetRef ( 12 ) ;
66+ a . GetRef ( 13 ) ^ = b . GetRef ( 13 ) ;
67+ a . GetRef ( 14 ) ^ = b . GetRef ( 14 ) ;
68+ a . GetRef ( 15 ) ^ = b . GetRef ( 15 ) ;
8369 }
8470
8571 [ Benchmark ( Description = @"Vector128" ) ]
8672 public void C ( )
8773 {
88- Xor ( _a . Span , _b . Span ) ;
74+ Span < byte > a = _a . Span ;
75+ Span < byte > b = _b . Span ;
8976
90- return ;
77+ ref Vector128 < byte > v0 = ref Unsafe . As < byte , Vector128 < byte > > ( ref MemoryMarshal . GetReference ( a ) ) ;
78+ ref Vector128 < byte > v1 = ref Unsafe . As < byte , Vector128 < byte > > ( ref MemoryMarshal . GetReference ( b ) ) ;
9179
92- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
93- static void Xor ( Span < byte > a , Span < byte > b )
94- {
95- Vector128 < byte > v0 = Unsafe . ReadUnaligned < Vector128 < byte > > ( ref MemoryMarshal . GetReference ( a ) ) ;
96- Vector128 < byte > v1 = Unsafe . ReadUnaligned < Vector128 < byte > > ( ref MemoryMarshal . GetReference ( b ) ) ;
97- ( v0 ^ v1 ) . CopyTo ( a ) ;
98- }
80+ v0 ^= v1 ;
9981 }
10082
10183 [ Benchmark ( Description = @"SSE2" ) ]
10284 public void D ( )
10385 {
104- Xor ( _a . Span , _b . Span ) ;
105-
106- return ;
86+ Span < byte > a = _a . Span ;
87+ Span < byte > b = _b . Span ;
10788
108- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
109- static unsafe void Xor ( Span < byte > a , Span < byte > b )
89+ unsafe
11090 {
11191 Vector128 < byte > v0 = Sse2 . LoadVector128 ( ( byte * ) Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( a ) ) ) ;
11292 Vector128 < byte > v1 = Sse2 . LoadVector128 ( ( byte * ) Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( b ) ) ) ;
@@ -117,12 +97,10 @@ static unsafe void Xor(Span<byte> a, Span<byte> b)
11797 [ Benchmark ( Description = @"Unsafe" ) ]
11898 public void E ( )
11999 {
120- Xor ( _a . Span , _b . Span ) ;
100+ Span < byte > a = _a . Span ;
101+ Span < byte > b = _b . Span ;
121102
122- return ;
123-
124- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
125- static unsafe void Xor ( Span < byte > a , Span < byte > b )
103+ unsafe
126104 {
127105 fixed ( byte * pa = & MemoryMarshal . GetReference ( a ) )
128106 fixed ( byte * pb = & MemoryMarshal . GetReference ( b ) )
@@ -138,12 +116,10 @@ static unsafe void Xor(Span<byte> a, Span<byte> b)
138116 [ Benchmark ( Description = @"Unsafe unrolling" ) ]
139117 public void F ( )
140118 {
141- Xor ( _a . Span , _b . Span ) ;
142-
143- return ;
119+ Span < byte > a = _a . Span ;
120+ Span < byte > b = _b . Span ;
144121
145- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
146- static unsafe void Xor ( Span < byte > a , Span < byte > b )
122+ unsafe
147123 {
148124 fixed ( byte * pa = & MemoryMarshal . GetReference ( a ) )
149125 fixed ( byte * pb = & MemoryMarshal . GetReference ( b ) )
@@ -167,4 +143,29 @@ static unsafe void Xor(Span<byte> a, Span<byte> b)
167143 }
168144 }
169145 }
146+
147+ [ Benchmark ( Description = @"UInt128" ) ]
148+ public void G( )
149+ {
150+ Span < byte > a = _a. Span;
151+ Span< byte > b = _b. Span;
152+
153+ ref UInt128 xa = ref Unsafe . As < byte , UInt128 > ( ref MemoryMarshal . GetReference ( a ) ) ;
154+ ref UInt128 xb = ref Unsafe. As < byte , UInt128 > ( ref MemoryMarshal . GetReference ( b ) ) ;
155+
156+ xa ^= xb;
157+ }
158+
159+ [ Benchmark ( Description = @"ulong" ) ]
160+ public void G2( )
161+ {
162+ Span < byte > a = _a. Span;
163+ Span< byte > b = _b. Span;
164+
165+ Span< ulong > xa = MemoryMarshal. Cast< byte , ulong > ( a ) ;
166+ ReadOnlySpan < ulong > xb = MemoryMarshal . Cast < byte , ulong > ( b ) ;
167+
168+ xa . GetRef ( 0 ) ^= xb . GetRef ( 0 ) ;
169+ xa . GetRef ( 1 ) ^= xb . GetRef( 1 ) ;
170+ }
170171}
0 commit comments