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:
parent
b0092bd84e
commit
519f984578
2 changed files with 41 additions and 12 deletions
|
@ -358,6 +358,9 @@ int cpu_msr_driver_close(struct msr_driver_t* drv)
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
/* from rdtsc.c: */
|
||||||
|
void sys_precise_clock(uint64_t *result);
|
||||||
|
int busy_loop_delay(int milliseconds);
|
||||||
|
|
||||||
static int rdmsr_supported(void)
|
static int rdmsr_supported(void)
|
||||||
{
|
{
|
||||||
|
@ -365,6 +368,21 @@ static int rdmsr_supported(void)
|
||||||
return id->flags[CPU_FEATURE_MSR];
|
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)
|
int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which)
|
||||||
{
|
{
|
||||||
uint64_t r;
|
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);
|
return set_error(ERR_HANDLE);
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case INFO_MPERF:
|
case INFO_MPERF:
|
||||||
{
|
return perfmsr_measure(handle, 0xe7);
|
||||||
err = cpu_rdmsr(handle, 0xe7, &r);
|
|
||||||
if (err) return CPU_INVALID_VALUE;
|
|
||||||
return (int) (r & 0x7fffffff);
|
|
||||||
}
|
|
||||||
case INFO_APERF:
|
case INFO_APERF:
|
||||||
{
|
return perfmsr_measure(handle, 0xe8);
|
||||||
err = cpu_rdmsr(handle, 0xe8, &r);
|
|
||||||
if (err) return CPU_INVALID_VALUE;
|
|
||||||
return (int) (r & 0x7fffffff);
|
|
||||||
}
|
|
||||||
case INFO_CUR_MULTIPLIER:
|
case INFO_CUR_MULTIPLIER:
|
||||||
{
|
{
|
||||||
err = cpu_rdmsr(handle, 0x2a, &r);
|
err = cpu_rdmsr(handle, 0x2a, &r);
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
static void sys_precise_clock(uint64_t *result)
|
void sys_precise_clock(uint64_t *result)
|
||||||
{
|
{
|
||||||
double c, f;
|
double c, f;
|
||||||
LARGE_INTEGER freq, counter;
|
LARGE_INTEGER freq, counter;
|
||||||
|
@ -42,7 +42,7 @@ static void sys_precise_clock(uint64_t *result)
|
||||||
#else
|
#else
|
||||||
/* assuming Linux, Mac OS or other POSIX */
|
/* assuming Linux, Mac OS or other POSIX */
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
static void sys_precise_clock(uint64_t *result)
|
void sys_precise_clock(uint64_t *result)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
@ -157,6 +157,25 @@ static int busy_loop(int amount)
|
||||||
return s;
|
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)
|
int cpu_clock_measure(int millis, int quad_check)
|
||||||
{
|
{
|
||||||
struct cpu_mark_t begin[4], end[4], temp, temp2;
|
struct cpu_mark_t begin[4], end[4], temp, temp2;
|
||||||
|
|
Loading…
Reference in a new issue