mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add SHA-256 benchmark with the option to display cycles per byte
This commit is contained in:
parent
1aa5c9438e
commit
1efcf3327c
3 changed files with 63 additions and 2 deletions
|
@ -60,6 +60,7 @@ namespace hactoolnet
|
||||||
new CliOption("hashedfs", 0, (o, a) => o.BuildHfs = true),
|
new CliOption("hashedfs", 0, (o, a) => o.BuildHfs = true),
|
||||||
new CliOption("title", 1, (o, a) => o.TitleId = ParseTitleId(a[0])),
|
new CliOption("title", 1, (o, a) => o.TitleId = ParseTitleId(a[0])),
|
||||||
new CliOption("bench", 1, (o, a) => o.BenchType = a[0]),
|
new CliOption("bench", 1, (o, a) => o.BenchType = a[0]),
|
||||||
|
new CliOption("cpufreq", 1, (o, a) => o.CpuFrequencyGhz = ParseDouble(a[0])),
|
||||||
|
|
||||||
new CliOption("replacefile", 2, (o, a) =>
|
new CliOption("replacefile", 2, (o, a) =>
|
||||||
{
|
{
|
||||||
|
@ -172,6 +173,16 @@ namespace hactoolnet
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static double ParseDouble(string input)
|
||||||
|
{
|
||||||
|
if (!double.TryParse(input, out double value))
|
||||||
|
{
|
||||||
|
PrintWithUsage($"Could not parse value \"{input}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private static void PrintWithUsage(string toPrint)
|
private static void PrintWithUsage(string toPrint)
|
||||||
{
|
{
|
||||||
Console.WriteLine(toPrint);
|
Console.WriteLine(toPrint);
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace hactoolnet
|
||||||
public bool BuildHfs;
|
public bool BuildHfs;
|
||||||
public ulong TitleId;
|
public ulong TitleId;
|
||||||
public string BenchType;
|
public string BenchType;
|
||||||
|
public double CpuFrequencyGhz;
|
||||||
|
|
||||||
public IntegrityCheckLevel IntegrityLevel
|
public IntegrityCheckLevel IntegrityLevel
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,9 @@ namespace hactoolnet
|
||||||
private const int BatchCipherBenchSize = 1024 * 1024;
|
private const int BatchCipherBenchSize = 1024 * 1024;
|
||||||
// ReSharper disable once UnusedMember.Local
|
// ReSharper disable once UnusedMember.Local
|
||||||
private const int SingleBlockCipherBenchSize = 1024 * 128;
|
private const int SingleBlockCipherBenchSize = 1024 * 128;
|
||||||
|
private const int ShaBenchSize = 1024 * 128;
|
||||||
|
|
||||||
|
private static double CpuFrequency { get; set; }
|
||||||
|
|
||||||
private static void CopyBenchmark(IStorage src, IStorage dst, int iterations, string label, IProgressReport logger)
|
private static void CopyBenchmark(IStorage src, IStorage dst, int iterations, string label, IProgressReport logger)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +189,7 @@ namespace hactoolnet
|
||||||
var input = new byte[BatchCipherBenchSize];
|
var input = new byte[BatchCipherBenchSize];
|
||||||
var output = new byte[BatchCipherBenchSize];
|
var output = new byte[BatchCipherBenchSize];
|
||||||
|
|
||||||
Func<double, string> resultPrinter = time => Util.GetBytesReadable((long)(BatchCipherBenchSize / time)) + "/s";
|
Func<double, string> resultPrinter = time => GetPerformanceString(time, BatchCipherBenchSize);
|
||||||
|
|
||||||
// Skip the first benchmark set if we don't have AES-NI intrinsics
|
// Skip the first benchmark set if we don't have AES-NI intrinsics
|
||||||
for (int i = Aes.IsAesNiSupported() ? 0 : 1; i < 2; i++)
|
for (int i = Aes.IsAesNiSupported() ? 0 : 1; i < 2; i++)
|
||||||
|
@ -235,7 +238,7 @@ namespace hactoolnet
|
||||||
var input = new byte[SingleBlockCipherBenchSize];
|
var input = new byte[SingleBlockCipherBenchSize];
|
||||||
var output = new byte[SingleBlockCipherBenchSize];
|
var output = new byte[SingleBlockCipherBenchSize];
|
||||||
|
|
||||||
Func<double, string> resultPrinter = time => Util.GetBytesReadable((long)(SingleBlockCipherBenchSize / time)) + "/s";
|
Func<double, string> resultPrinter = time => GetPerformanceString(time, SingleBlockCipherBenchSize);
|
||||||
|
|
||||||
bench.Register("AES single-block encrypt", () => { }, EncryptBlocks, resultPrinter);
|
bench.Register("AES single-block encrypt", () => { }, EncryptBlocks, resultPrinter);
|
||||||
bench.Register("AES single-block decrypt", () => { }, DecryptBlocks, resultPrinter);
|
bench.Register("AES single-block decrypt", () => { }, DecryptBlocks, resultPrinter);
|
||||||
|
@ -284,6 +287,35 @@ namespace hactoolnet
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void RegisterShaBenchmarks(MultiBenchmark bench)
|
||||||
|
{
|
||||||
|
var input = new byte[ShaBenchSize];
|
||||||
|
var digest = new byte[Sha256.DigestSize];
|
||||||
|
|
||||||
|
Func<double, string> resultPrinter = time => GetPerformanceString(time, ShaBenchSize);
|
||||||
|
|
||||||
|
RegisterHash("SHA-256 built-in", () => new Sha256Generator());
|
||||||
|
|
||||||
|
void RegisterHash(string name, Func<IHash> hashGenerator)
|
||||||
|
{
|
||||||
|
IHash hash = null;
|
||||||
|
|
||||||
|
Action setup = () =>
|
||||||
|
{
|
||||||
|
hash = hashGenerator();
|
||||||
|
hash.Initialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
Action action = () =>
|
||||||
|
{
|
||||||
|
hash.Update(input);
|
||||||
|
hash.GetHash(digest);
|
||||||
|
};
|
||||||
|
|
||||||
|
bench.Register(name, setup, action, resultPrinter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RunCipherBenchmark(Func<ICipher> cipherNet, Func<ICipher> cipherLibHac,
|
private static void RunCipherBenchmark(Func<ICipher> cipherNet, Func<ICipher> cipherLibHac,
|
||||||
CipherTaskSeparate function, bool benchBlocked, string label, IProgressReport logger)
|
CipherTaskSeparate function, bool benchBlocked, string label, IProgressReport logger)
|
||||||
{
|
{
|
||||||
|
@ -341,8 +373,24 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetPerformanceString(double seconds, long bytes)
|
||||||
|
{
|
||||||
|
string cyclesPerByteString = string.Empty;
|
||||||
|
double bytesPerSec = bytes / seconds;
|
||||||
|
|
||||||
|
if (CpuFrequency > 0)
|
||||||
|
{
|
||||||
|
double cyclesPerByte = CpuFrequency / bytesPerSec;
|
||||||
|
cyclesPerByteString = $" ({cyclesPerByte:N3}x)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Util.GetBytesReadable((long)bytesPerSec) + "/s" + cyclesPerByteString;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Process(Context ctx)
|
public static void Process(Context ctx)
|
||||||
{
|
{
|
||||||
|
CpuFrequency = ctx.Options.CpuFrequencyGhz * 1_000_000_000;
|
||||||
|
|
||||||
switch (ctx.Options.BenchType?.ToLower())
|
switch (ctx.Options.BenchType?.ToLower())
|
||||||
{
|
{
|
||||||
case "aesctr":
|
case "aesctr":
|
||||||
|
@ -465,6 +513,7 @@ namespace hactoolnet
|
||||||
|
|
||||||
RegisterAesSequentialBenchmarks(bench);
|
RegisterAesSequentialBenchmarks(bench);
|
||||||
RegisterAesSingleBlockBenchmarks(bench);
|
RegisterAesSingleBlockBenchmarks(bench);
|
||||||
|
RegisterShaBenchmarks(bench);
|
||||||
|
|
||||||
bench.Run();
|
bench.Run();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue