Skip to content

Commit f3dbfe1

Browse files
committed
First SIMD version
Just XOR operation
1 parent 2d649c4 commit f3dbfe1

File tree

5 files changed

+976
-612
lines changed

5 files changed

+976
-612
lines changed

benchmarks/Program.cs

+158-83
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22

33
using BenchmarkDotNet.Attributes;
44
using BenchmarkDotNet.Running;
@@ -8,109 +8,184 @@
88

99
namespace benchmarks
1010
{
11-
[MemoryDiagnoser]
12-
public class OriginalVsAdjusted
13-
{
14-
private const int dataLength1 = 64;
15-
private const int dataLength2 = 1024;
16-
private const int dataLength3 = 1024*1024;
17-
18-
private readonly byte[] data1;
19-
private readonly byte[] data2;
20-
private readonly byte[] data3;
21-
22-
private readonly ChaCha20Cipher.ChaCha20Cipher original1 = null;
23-
private readonly ChaCha20Cipher.ChaCha20Cipher original2 = null;
24-
private readonly ChaCha20Cipher.ChaCha20Cipher original3 = null;
25-
26-
private readonly CSChaCha20.ChaCha20 adjusted1 = null;
27-
private readonly CSChaCha20.ChaCha20 adjusted2 = null;
28-
private readonly CSChaCha20.ChaCha20 adjusted3 = null;
29-
30-
private static readonly byte[] key = new byte[32] {
31-
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
11+
[MemoryDiagnoser]
12+
public class OriginalVsAdjusted
13+
{
14+
private const int dataLength1 = 64;
15+
private const int dataLength2 = 1024;
16+
private const int dataLength3 = 1024*1024;
17+
18+
private readonly byte[] data1;
19+
private readonly byte[] data2;
20+
private readonly byte[] data3;
21+
22+
private readonly ChaCha20Cipher.ChaCha20Cipher original1 = null;
23+
private readonly ChaCha20Cipher.ChaCha20Cipher original2 = null;
24+
private readonly ChaCha20Cipher.ChaCha20Cipher original3 = null;
25+
26+
private readonly CSChaCha20.ChaCha20 adjustedNoSimd1 = null;
27+
private readonly CSChaCha20.ChaCha20 adjustedNoSimd2 = null;
28+
private readonly CSChaCha20.ChaCha20 adjustedNoSimd3 = null;
29+
30+
private readonly CSChaCha20.ChaCha20 adjusted_V128_1 = null;
31+
private readonly CSChaCha20.ChaCha20 adjusted_V128_2 = null;
32+
private readonly CSChaCha20.ChaCha20 adjusted_V128_3 = null;
33+
34+
private readonly CSChaCha20.ChaCha20 adjusted_V256_1 = null;
35+
private readonly CSChaCha20.ChaCha20 adjusted_V256_2 = null;
36+
private readonly CSChaCha20.ChaCha20 adjusted_V256_3 = null;
37+
38+
private readonly CSChaCha20.ChaCha20 adjusted_V512_1 = null;
39+
private readonly CSChaCha20.ChaCha20 adjusted_V512_2 = null;
40+
private readonly CSChaCha20.ChaCha20 adjusted_V512_3 = null;
41+
42+
private static readonly byte[] key = new byte[32] {
43+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
3244
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
3345
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
3446
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
35-
};
36-
37-
private static readonly byte[] nonce = new byte[12] { 0x00, 0x09, 0x00, 0x00, 0xFF, 0x20, 0x12, 0x00, 0x00, 0x8b, 0x00, 0x02 };
38-
private static readonly uint counter = 13;
47+
};
48+
49+
private static readonly byte[] nonce = new byte[12] { 0x00, 0x09, 0x00, 0x00, 0xFF, 0x20, 0x12, 0x00, 0x00, 0x8b, 0x00, 0x02 };
50+
private static readonly uint counter = 13;
3951

40-
private byte[] outputForOriginal1;
41-
private byte[] outputForOriginal2;
42-
private byte[] outputForOriginal3;
52+
private byte[] outputForOriginal1;
53+
private byte[] outputForOriginal2;
54+
private byte[] outputForOriginal3;
4355

44-
private byte[] outputForAdjusted1;
45-
private byte[] outputForAdjusted2;
46-
private byte[] outputForAdjusted3;
56+
private byte[] output_For_Adjusted_NoSimd_1;
57+
private byte[] output_For_Adjusted_NoSimd_2;
58+
private byte[] output_For_Adjusted_NoSimd_3;
4759

48-
public OriginalVsAdjusted()
49-
{
50-
// Arrays for outputs
51-
this.outputForOriginal1 = new byte[dataLength1];
52-
this.outputForOriginal2 = new byte[dataLength2];
53-
this.outputForOriginal3 = new byte[dataLength3];
60+
private byte[] output_For_Adjusted_V128_1;
61+
private byte[] output_For_Adjusted_V128_2;
62+
private byte[] output_For_Adjusted_V128_3;
5463

55-
this.outputForAdjusted1 = new byte[dataLength1];
56-
this.outputForAdjusted2 = new byte[dataLength2];
57-
this.outputForAdjusted3 = new byte[dataLength3];
64+
private byte[] output_For_Adjusted_V256_1;
65+
private byte[] output_For_Adjusted_V256_2;
66+
private byte[] output_For_Adjusted_V256_3;
5867

59-
// Generate inputs
60-
Random rng = new Random(Seed: 1337);
68+
private byte[] output_For_Adjusted_V512_1;
69+
private byte[] output_For_Adjusted_V512_2;
70+
private byte[] output_For_Adjusted_V512_3;
6171

62-
this.data1 = new byte[dataLength1];
63-
rng.NextBytes(this.data1);
72+
public OriginalVsAdjusted()
73+
{
74+
// Arrays for outputs
75+
this.outputForOriginal1 = new byte[dataLength1];
76+
this.outputForOriginal2 = new byte[dataLength2];
77+
this.outputForOriginal3 = new byte[dataLength3];
6478

65-
this.data2 = new byte[dataLength2];
66-
rng.NextBytes(this.data2);
79+
this.output_For_Adjusted_NoSimd_1 = new byte[dataLength1];
80+
this.output_For_Adjusted_NoSimd_2 = new byte[dataLength2];
81+
this.output_For_Adjusted_NoSimd_3 = new byte[dataLength3];
6782

68-
this.data3 = new byte[dataLength3];
69-
rng.NextBytes(this.data3);
83+
this.output_For_Adjusted_V128_1 = new byte[dataLength1];
84+
this.output_For_Adjusted_V128_2 = new byte[dataLength2];
85+
this.output_For_Adjusted_V128_3 = new byte[dataLength3];
7086

71-
// Set encrypters
72-
this.original1 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
73-
this.original2 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
74-
this.original3 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
87+
this.output_For_Adjusted_V256_1 = new byte[dataLength1];
88+
this.output_For_Adjusted_V256_2 = new byte[dataLength2];
89+
this.output_For_Adjusted_V256_3 = new byte[dataLength3];
7590

76-
this.adjusted1 = new CSChaCha20.ChaCha20(key, nonce, counter);
77-
this.adjusted2 = new CSChaCha20.ChaCha20(key, nonce, counter);
78-
this.adjusted3 = new CSChaCha20.ChaCha20(key, nonce, counter);
79-
}
91+
this.output_For_Adjusted_V512_1 = new byte[dataLength1];
92+
this.output_For_Adjusted_V512_2 = new byte[dataLength2];
93+
this.output_For_Adjusted_V512_3 = new byte[dataLength3];
8094

81-
#region 64 bytes
82-
[Benchmark]
83-
public void Original64Bytes() => this.original1.EncryptBytes(this.outputForOriginal1, this.data1, dataLength1);
95+
// Generate inputs
96+
Random rng = new Random(Seed: 1337);
8497

85-
[Benchmark]
86-
public void Adjusted64Bytes() => this.adjusted1.EncryptBytes(this.outputForAdjusted1, this.data1, dataLength1);
98+
this.data1 = new byte[dataLength1];
99+
rng.NextBytes(this.data1);
87100

88-
#endregion // 64 bytes
101+
this.data2 = new byte[dataLength2];
102+
rng.NextBytes(this.data2);
89103

90-
#region 1024 bytes
91-
[Benchmark]
92-
public void Original1024Bytes() => this.original2.EncryptBytes(this.outputForOriginal2, this.data2, dataLength2);
104+
this.data3 = new byte[dataLength3];
105+
rng.NextBytes(this.data3);
93106

94-
[Benchmark]
95-
public void Adjusted1024Bytes() => this.adjusted2.EncryptBytes(this.outputForAdjusted2, this.data2, dataLength2);
107+
// Set encrypters
108+
this.original1 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
109+
this.original2 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
110+
this.original3 = new ChaCha20Cipher.ChaCha20Cipher(key, nonce, counter);
96111

97-
#endregion // 1024 bytes
112+
this.adjustedNoSimd1 = new CSChaCha20.ChaCha20(key, nonce, counter);
113+
this.adjustedNoSimd2 = new CSChaCha20.ChaCha20(key, nonce, counter);
114+
this.adjustedNoSimd3 = new CSChaCha20.ChaCha20(key, nonce, counter);
98115

99-
#region 1 MiB
100-
[Benchmark]
101-
public void Original1MiBBytes() => this.original3.EncryptBytes(this.outputForOriginal3, this.data3, dataLength3);
116+
this.adjusted_V128_1 = new CSChaCha20.ChaCha20(key, nonce, counter);
117+
this.adjusted_V128_2 = new CSChaCha20.ChaCha20(key, nonce, counter);
118+
this.adjusted_V128_3 = new CSChaCha20.ChaCha20(key, nonce, counter);
102119

103-
[Benchmark]
104-
public void Adjusted1MibBytes() => this.adjusted3.EncryptBytes(this.outputForAdjusted3, this.data3, dataLength3);
120+
this.adjusted_V256_1 = new CSChaCha20.ChaCha20(key, nonce, counter);
121+
this.adjusted_V256_2 = new CSChaCha20.ChaCha20(key, nonce, counter);
122+
this.adjusted_V256_3 = new CSChaCha20.ChaCha20(key, nonce, counter);
105123

106-
#endregion // 1 MiB
107-
}
124+
this.adjusted_V512_1 = new CSChaCha20.ChaCha20(key, nonce, counter);
125+
this.adjusted_V512_2 = new CSChaCha20.ChaCha20(key, nonce, counter);
126+
this.adjusted_V512_3 = new CSChaCha20.ChaCha20(key, nonce, counter);
127+
}
108128

109-
class Program
110-
{
111-
static void Main(string[] args)
112-
{
113-
var summary = BenchmarkRunner.Run<OriginalVsAdjusted>();
114-
}
115-
}
129+
#region 64 bytes
130+
[Benchmark]
131+
public void Original_64_Bytes() => this.original1.EncryptBytes(this.outputForOriginal1, this.data1, dataLength1);
132+
133+
[Benchmark]
134+
public void Adjusted_NoSimd_64Bytes() => this.adjustedNoSimd1.EncryptBytes(this.output_For_Adjusted_NoSimd_1, this.data1, dataLength1, SimdMode.None);
135+
136+
[Benchmark]
137+
public void Adjusted_V128_64Bytes() => this.adjusted_V128_1.EncryptBytes(this.output_For_Adjusted_V128_1, this.data1, dataLength1, SimdMode.V128);
138+
139+
[Benchmark]
140+
public void Adjusted_V256_64Bytes() => this.adjusted_V256_1.EncryptBytes(this.output_For_Adjusted_V256_1, this.data1, dataLength1, SimdMode.V256);
141+
142+
[Benchmark]
143+
public void Adjusted_V512_64Bytes() => this.adjusted_V512_1.EncryptBytes(this.output_For_Adjusted_V512_1, this.data1, dataLength1, SimdMode.V512);
144+
145+
#endregion // 64 bytes
146+
147+
#region 1024 bytes
148+
[Benchmark]
149+
public void Original_1024_Bytes() => this.original2.EncryptBytes(this.outputForOriginal2, this.data2, dataLength2);
150+
151+
[Benchmark]
152+
public void Adjusted_NoSimd_1024_Bytes() => this.adjustedNoSimd2.EncryptBytes(this.output_For_Adjusted_NoSimd_2, this.data2, dataLength2, SimdMode.None);
153+
154+
[Benchmark]
155+
public void Adjusted_V128_1024_Bytes() => this.adjusted_V128_2.EncryptBytes(this.output_For_Adjusted_V128_2, this.data2, dataLength2, SimdMode.V128);
156+
157+
[Benchmark]
158+
public void Adjusted_V256_1024_Bytes() => this.adjusted_V256_2.EncryptBytes(this.output_For_Adjusted_V256_2, this.data2, dataLength2, SimdMode.V256);
159+
160+
[Benchmark]
161+
public void Adjusted_V512_1024_Bytes() => this.adjusted_V512_2.EncryptBytes(this.output_For_Adjusted_V512_2, this.data2, dataLength2, SimdMode.V512);
162+
163+
#endregion // 1024 bytes
164+
165+
#region 1 MiB
166+
[Benchmark]
167+
public void Original_1MiB_Bytes() => this.original3.EncryptBytes(this.outputForOriginal3, this.data3, dataLength3);
168+
169+
[Benchmark]
170+
public void Adjusted_NoSimd_1Mib_Bytes() => this.adjustedNoSimd3.EncryptBytes(this.output_For_Adjusted_NoSimd_3, this.data3, dataLength3, SimdMode.None);
171+
172+
[Benchmark]
173+
public void Adjusted_V128_1Mib_Bytes() => this.adjusted_V128_3.EncryptBytes(this.output_For_Adjusted_V128_3, this.data3, dataLength3, SimdMode.V128);
174+
175+
[Benchmark]
176+
public void Adjusted_V256_1Mib_Bytes() => this.adjusted_V256_3.EncryptBytes(this.output_For_Adjusted_V256_3, this.data3, dataLength3, SimdMode.V256);
177+
178+
[Benchmark]
179+
public void Adjusted_V512_1Mib_Bytes() => this.adjusted_V512_3.EncryptBytes(this.output_For_Adjusted_V512_3, this.data3, dataLength3, SimdMode.V512);
180+
181+
#endregion // 1 MiB
182+
}
183+
184+
class Program
185+
{
186+
static void Main(string[] args)
187+
{
188+
var summary = BenchmarkRunner.Run<OriginalVsAdjusted>();
189+
}
190+
}
116191
}

harness/harness.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>

0 commit comments

Comments
 (0)