From 4a18d98251d8cba18a674fccd41d7c2fa8012d0d Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Thu, 1 Oct 2020 13:35:16 +0200 Subject: [PATCH] calculate cpu freq not hardcoded to 3 GHz. Some code is based on GH #125, but this result is not really good. On linux I found an easy way. --- Platform.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ Platform.h | 1 + SpeedTest.cpp | 9 +++++--- main.cpp | 2 +- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Platform.cpp b/Platform.cpp index 6aab60ed..408303c0 100644 --- a/Platform.cpp +++ b/Platform.cpp @@ -39,3 +39,60 @@ void SetAffinity ( int /*cpu*/ ) } #endif + + +// From https://encode.su/threads/3389-Code-snippet-to-compute-CPU-frequency +// Perform CYCLES simple in-order operations +static unsigned cycles_loop(unsigned cycles) +{ + unsigned a = rand(), b = rand(), x = rand(); + for (unsigned i=0; i < cycles/10; i++) + { + x = (x + a) ^ b; + x = (x + a) ^ b; + x = (x + a) ^ b; + x = (x + a) ^ b; + x = (x + a) ^ b; + } + return x; +} + +#ifdef __linux__ +#include +#include +#include +#endif + +double cpu_freq() +{ + const unsigned cycles = 100*1000*1000; + unsigned x = cycles_loop(cycles/10); // warmup +#ifdef __linux__ + std::ifstream curfreqfile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"); + if (curfreqfile.is_open()) { + std::string line; + getline(curfreqfile, line); + long res = strtol(line.c_str(), NULL, 10); + curfreqfile.close(); + fprintf (stderr, "scaling_cpu_freq: %ld\n", res); + fflush(NULL); + if (res > 1000) + return (double) res / 1000000.0; // 1801310, 2452626 + } +#endif + double result = 3.0; + const uint64_t t1 = timer_start(); + x += cycles_loop(cycles); + const uint64_t t2 = timer_end(); + // constant adjustment factor, when compared to scaling_cur_freq + // ADJ = (res / 1000000.0) / (t2-t1) + const double ADJ = 236163824.32526; + if (x) + result = (double) (ADJ / (t2-t1)); + if (result < 0.001) { + fprintf (stderr, "%u pseudo-cycles, %lu time-cycles\n", cycles, (unsigned long)(t2-t1)); + return 3.0; + } + return result; + //printf("CPU freq %.2f GHz", (cycles/1e9)/(t2-t1)); +} diff --git a/Platform.h b/Platform.h index ae5f1491..9d461d39 100644 --- a/Platform.h +++ b/Platform.h @@ -4,6 +4,7 @@ #pragma once void SetAffinity ( int cpu ); +double cpu_freq(); #ifndef __x86_64__ #if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) diff --git a/SpeedTest.cpp b/SpeedTest.cpp index 7f8b138f..ed89ecf0 100644 --- a/SpeedTest.cpp +++ b/SpeedTest.cpp @@ -268,6 +268,7 @@ void BulkSpeedTest ( pfHash hash, uint32_t seed ) printf("Bulk speed test - %d-byte keys\n",blocksize); double sumbpc = 0.0; + double freq = cpu_freq(); volatile double warmup_cycles = SpeedTest(hash,seed,trials,blocksize,0); @@ -277,12 +278,14 @@ void BulkSpeedTest ( pfHash hash, uint32_t seed ) double bestbpc = double(blocksize)/cycles; - double bestbps = (bestbpc * 3000000000.0 / 1048576.0); - printf("Alignment %2d - %6.3f bytes/cycle - %7.2f MiB/sec @ 3 ghz\n",align,bestbpc,bestbps); + double bestbps = (bestbpc * freq * 1000000000.0 / 1048576.0); + printf("Alignment %2d - %6.3f bytes/cycle - %7.2f MiB/sec @ %0.2f GHz\n",align,bestbpc,bestbps,freq); sumbpc += bestbpc; } sumbpc = sumbpc / 8.0; - printf("Average - %6.3f bytes/cycle - %7.2f MiB/sec @ 3 ghz\n",sumbpc,(sumbpc * 3000000000.0 / 1048576.0)); + printf("Average - %6.3f bytes/cycle - %7.2f MiB/sec @ %0.2f GHz\n",sumbpc, + (sumbpc * freq * 1000000000.0 / 1048576.0), + freq); fflush(NULL); } diff --git a/main.cpp b/main.cpp index f742fbf9..4546245f 100644 --- a/main.cpp +++ b/main.cpp @@ -631,7 +631,7 @@ void test ( hashfunc hash, HashInfo* info ) sum += TinySpeedTest(hashfunc(info->hash),sizeof(hashtype),j,info->verification,true); } g_speed = sum = sum / 31.0; - printf("Average %6.3f cycles/hash\n",sum); + printf("Average %8.3f cycles/hash\n",sum); printf("\n"); fflush(NULL); } else {