1
0
Fork 0
mirror of https://github.com/anrieff/libcpuid synced 2024-11-10 22:59:13 +00:00

Added MPERF and APERF MSR incrementation speed calculation using a 10ms delay loop

git-svn-id: https://svn.code.sf.net/p/libcpuid/code/HEAD/libcpuid@75 3b4be424-7ac5-41d7-8526-f4ddcb85d872
This commit is contained in:
Veselin Georgiev 2009-10-05 01:08:36 +00:00
parent b0092bd84e
commit 519f984578
2 changed files with 41 additions and 12 deletions

View file

@ -358,6 +358,9 @@ int cpu_msr_driver_close(struct msr_driver_t* drv)
#endif /* _WIN32 */
/* from rdtsc.c: */
void sys_precise_clock(uint64_t *result);
int busy_loop_delay(int milliseconds);
static int rdmsr_supported(void)
{
@ -365,6 +368,21 @@ static int rdmsr_supported(void)
return id->flags[CPU_FEATURE_MSR];
}
static int perfmsr_measure(struct msr_driver_t* handle, int msr)
{
int err;
uint64_t a, b;
uint64_t x, y;
err = cpu_rdmsr(handle, msr, &x);
if (err) return CPU_INVALID_VALUE;
sys_precise_clock(&a);
busy_loop_delay(10);
cpu_rdmsr(handle, msr, &y);
sys_precise_clock(&b);
if (a >= b || x > y) return CPU_INVALID_VALUE;
return (y - x) / (b - a);
}
int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which)
{
uint64_t r;
@ -374,17 +392,9 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which)
return set_error(ERR_HANDLE);
switch (which) {
case INFO_MPERF:
{
err = cpu_rdmsr(handle, 0xe7, &r);
if (err) return CPU_INVALID_VALUE;
return (int) (r & 0x7fffffff);
}
return perfmsr_measure(handle, 0xe7);
case INFO_APERF:
{
err = cpu_rdmsr(handle, 0xe8, &r);
if (err) return CPU_INVALID_VALUE;
return (int) (r & 0x7fffffff);
}
return perfmsr_measure(handle, 0xe8);
case INFO_CUR_MULTIPLIER:
{
err = cpu_rdmsr(handle, 0x2a, &r);

View file

@ -29,7 +29,7 @@
#ifdef _WIN32
#include <windows.h>
static void sys_precise_clock(uint64_t *result)
void sys_precise_clock(uint64_t *result)
{
double c, f;
LARGE_INTEGER freq, counter;
@ -42,7 +42,7 @@ static void sys_precise_clock(uint64_t *result)
#else
/* assuming Linux, Mac OS or other POSIX */
#include <sys/time.h>
static void sys_precise_clock(uint64_t *result)
void sys_precise_clock(uint64_t *result)
{
struct timeval tv;
gettimeofday(&tv, NULL);
@ -157,6 +157,25 @@ static int busy_loop(int amount)
return s;
}
int busy_loop_delay(int milliseconds)
{
int cycles = 0, r = 0, first = 1;
uint64_t a, b, c;
sys_precise_clock(&a);
while (1) {
sys_precise_clock(&c);
if ((c - a) / 1000 > milliseconds) return r;
r += busy_loop(cycles);
if (first) {
first = 0;
} else {
if (c - b < 1000) cycles *= 2;
if (c - b > 10000) cycles /= 2;
}
b = c;
}
}
int cpu_clock_measure(int millis, int quad_check)
{
struct cpu_mark_t begin[4], end[4], temp, temp2;