加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
nano_stopwatch.h 3.02 KB
一键复制 编辑 原始数据 按行查看 历史
mrtang 提交于 2022-12-03 19:38 . add support for mac
#pragma once
// view it on gitee: https://gitee.com/tiger_git/nano_stopwatch
#if _WIN32
#include <windows.h>
#include <Psapi.h>
#include <powrprof.h>
typedef struct _PROCESSOR_POWER_INFORMATION
{
ULONG Number;
ULONG MaxMhz;
ULONG CurrentMhz;
ULONG MhzLimit;
ULONG MaxIdleState;
ULONG CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
#ifdef _MSC_VER
#pragma comment(lib, "PowrProf.lib")
#endif
#elif __Linux__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#elif __APPLE__
#include <mach/mach_time.h>
#include <unistd.h>
#endif
typedef struct
{
unsigned long long cpu_cycle;
} nano_stopwatch_t;
static inline double __nano_stopwatch_get_cpu_freq_mhz() {
double mhz = -1;
#if _WIN32
SYSTEM_INFO si = {0};
GetSystemInfo(&si);
PROCESSOR_POWER_INFORMATION ppi[128];
DWORD dwSize =
sizeof(PROCESSOR_POWER_INFORMATION) * si.dwNumberOfProcessors;
memset(&ppi, 0, dwSize);
LONG ret =
CallNtPowerInformation(ProcessorInformation, NULL, 0, &ppi[0], dwSize);
if (ret != 0 || ppi[0].MaxMhz <= 0) {
return -1;
}
mhz = ppi[0].MaxMhz;
#elif __linux__
FILE* fp = popen(
"cat /proc/cpuinfo | grep \"cpu.*MHz\" | sed -e 's/.*:[^0-9]//'", "r");
if (fp) {
char buf[32];
if (fgets(buf, sizeof(buf), fp)) {
mhz = atof(buf);
}
fclose(fp);
}
#elif __APPLE__
mach_timebase_info_data_t info;
kern_return_t err = mach_timebase_info(&info);
if (err == 0) {
mhz = (double)info.denom / info.numer * 1000;
}
#endif
return mhz;
}
static inline long long __nano_stopwatch_get_cpu_cycle() {
#if _WIN32
return __rdtsc();
#elif __linux__
unsigned int low, high;
__asm__ __volatile__("rdtsc" : "=a"(low), "=d"(high));
return (unsigned long long)high << 32 | low;
#elif __APPLE__
return mach_absolute_time();
#endif
}
static double __nano_stopwatch_cpu_freq_per_ns = -1;
static inline nano_stopwatch_t nano_stopwatch_init() {
nano_stopwatch_t nsw = {0};
static unsigned char inited = 0;
if (inited == 0) {
__nano_stopwatch_cpu_freq_per_ns =
__nano_stopwatch_get_cpu_freq_mhz() / 1000.0;
inited = 1;
}
nsw.cpu_cycle = __nano_stopwatch_get_cpu_cycle();
return nsw;
}
static inline void nano_stopwatch_reset(nano_stopwatch_t* nsw) {
nsw->cpu_cycle = __nano_stopwatch_get_cpu_cycle();
}
static inline double nano_stopwatch_elapsed_ns(nano_stopwatch_t* nsw) {
return (__nano_stopwatch_get_cpu_cycle() - nsw->cpu_cycle) /
__nano_stopwatch_cpu_freq_per_ns;
}
// short name you will like
#define nsw_t nano_stopwatch_t
#define nsw_init() nano_stopwatch_init()
#define nsw_reset(_nsw) nano_stopwatch_reset((_nsw))
#define nsw_elapsed_ns(_nsw) nano_stopwatch_elapsed_ns((_nsw))
#define nsw_elapsed_us(_nsw) (nano_stopwatch_elapsed_ns((_nsw)) / 1000.0)
#define nsw_elapsed_ms(_nsw) (nsw_elapsed_us((_nsw)) / 1000.0)
#define nsw_elapsed_s(_nsw) (nsw_elapsed_ms((_nsw)) / 1000.0)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化