mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add crypto benchmarks
This commit is contained in:
parent
ff23a9179c
commit
e02e719ea5
2 changed files with 136 additions and 0 deletions
75
src/hactoolnet/MultiBenchmark.cs
Normal file
75
src/hactoolnet/MultiBenchmark.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace hactoolnet
|
||||
{
|
||||
internal class MultiBenchmark
|
||||
{
|
||||
public int RunsNeeded { get; set; } = 500;
|
||||
|
||||
private List<BenchmarkItem> Benchmarks { get; } = new List<BenchmarkItem>();
|
||||
|
||||
public void Register(string name, Action setupAction, Action runAction, Func<double, string> resultPrinter)
|
||||
{
|
||||
var benchmark = new BenchmarkItem
|
||||
{
|
||||
Name = name,
|
||||
Setup = setupAction,
|
||||
Run = runAction,
|
||||
PrintResult = resultPrinter
|
||||
};
|
||||
|
||||
Benchmarks.Add(benchmark);
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
foreach (BenchmarkItem item in Benchmarks)
|
||||
{
|
||||
RunBenchmark(item);
|
||||
|
||||
Console.WriteLine($"{item.Name}: {item.Result}");
|
||||
}
|
||||
}
|
||||
|
||||
private void RunBenchmark(BenchmarkItem item)
|
||||
{
|
||||
double fastestRun = double.MaxValue;
|
||||
var watch = new Stopwatch();
|
||||
|
||||
int runsSinceLastBest = 0;
|
||||
|
||||
while (runsSinceLastBest < RunsNeeded)
|
||||
{
|
||||
runsSinceLastBest++;
|
||||
item.Setup();
|
||||
|
||||
watch.Restart();
|
||||
item.Run();
|
||||
watch.Stop();
|
||||
|
||||
if (fastestRun > watch.Elapsed.TotalSeconds)
|
||||
{
|
||||
fastestRun = watch.Elapsed.TotalSeconds;
|
||||
|
||||
runsSinceLastBest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
item.Time = fastestRun;
|
||||
item.Result = item.PrintResult(item.Time);
|
||||
}
|
||||
|
||||
private class BenchmarkItem
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public double Time { get; set; }
|
||||
public string Result { get; set; }
|
||||
|
||||
public Action Setup { get; set; }
|
||||
public Action Run { get; set; }
|
||||
public Func<double, string> PrintResult { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ namespace hactoolnet
|
|||
private const int BlockSizeBlocked = 0x10;
|
||||
private const int BlockSizeSeparate = 0x10;
|
||||
|
||||
private const int BatchCipherBenchSize = 1024 * 1024;
|
||||
|
||||
private static void CopyBenchmark(IStorage src, IStorage dst, int iterations, string label, IProgressReport logger)
|
||||
{
|
||||
// Warmup
|
||||
|
@ -171,6 +173,53 @@ namespace hactoolnet
|
|||
logger.LogMessage($"{label}{averageRate}/s, fastest run: {fastestRate}/s, slowest run: {slowestRate}/s");
|
||||
}
|
||||
|
||||
private static void RegisterAllCipherBenchmarks(MultiBenchmark bench)
|
||||
{
|
||||
var input = new byte[BatchCipherBenchSize];
|
||||
var output = new byte[BatchCipherBenchSize];
|
||||
|
||||
Func<double, string> resultPrinter = time => Util.GetBytesReadable((long)(BatchCipherBenchSize / time)) + "/s";
|
||||
|
||||
// Skip the first benchmark set if we don't have AES-NI intrinsics
|
||||
for (int i = Aes.IsAesNiSupported() ? 0 : 1; i < 2; i++)
|
||||
{
|
||||
// Prefer .NET crypto on the second set
|
||||
string nameSuffix = i == 1 ? "built-in " : string.Empty;
|
||||
bool preferDotNetImpl = i == 1;
|
||||
|
||||
RegisterCipher($"AES-ECB {nameSuffix}encrypt",
|
||||
() => Aes.CreateEcbEncryptor(new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-ECB {nameSuffix}decrypt",
|
||||
() => Aes.CreateEcbDecryptor(new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-CBC {nameSuffix}encrypt",
|
||||
() => Aes.CreateCbcEncryptor(new byte[0x10], new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-CBC {nameSuffix}decrypt",
|
||||
() => Aes.CreateCbcDecryptor(new byte[0x10], new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-CTR {nameSuffix}decrypt",
|
||||
() => Aes.CreateCtrDecryptor(new byte[0x10], new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-XTS {nameSuffix}encrypt",
|
||||
() => Aes.CreateXtsEncryptor(new byte[0x10], new byte[0x10], new byte[0x10], preferDotNetImpl));
|
||||
|
||||
RegisterCipher($"AES-XTS {nameSuffix}decrypt",
|
||||
() => Aes.CreateXtsDecryptor(new byte[0x10], new byte[0x10], new byte[0x10], preferDotNetImpl));
|
||||
}
|
||||
|
||||
void RegisterCipher(string name, Func<ICipher> cipherGenerator)
|
||||
{
|
||||
ICipher cipher = null;
|
||||
|
||||
Action setup = () => cipher = cipherGenerator();
|
||||
Action action = () => cipher.Transform(input, output);
|
||||
|
||||
bench.Register(name, setup, action, resultPrinter);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RunCipherBenchmark(Func<ICipher> cipherNet, Func<ICipher> cipherLibHac,
|
||||
CipherTaskSeparate function, bool benchBlocked, string label, IProgressReport logger)
|
||||
{
|
||||
|
@ -295,6 +344,7 @@ namespace hactoolnet
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case "aescbcnew":
|
||||
{
|
||||
Func<ICipher> encryptorNet = () => Aes.CreateCbcEncryptor(new byte[0x10], new byte[0x10], true);
|
||||
|
@ -325,6 +375,7 @@ namespace hactoolnet
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case "aesxtsnew":
|
||||
{
|
||||
Func<ICipher> encryptorNet = () => Aes.CreateXtsEncryptor(new byte[0x10], new byte[0x10], new byte[0x10], true);
|
||||
|
@ -344,6 +395,16 @@ namespace hactoolnet
|
|||
break;
|
||||
}
|
||||
|
||||
case "crypto":
|
||||
{
|
||||
var bench = new MultiBenchmark();
|
||||
|
||||
RegisterAllCipherBenchmarks(bench);
|
||||
|
||||
bench.Run();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ctx.Logger.LogMessage("Unknown benchmark type.");
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue