获取机器当前CPU频率

                                         获取机器当前CPU频率

struct perf_cpu_info
{
    int tsc;
    int index;
    int mhz;
};
struct perf_cpu_info *cpu_list;

static unsigned long long native_read_tsc(void)
{
    unsigned long long val;
    asm volatile("rdtsc": "=A" (val));
    return val;
}

unsigned int calibrate_tsc(void)
{
    unsigned long long val;
    unsigned long long val2;
    long long diff = 0;
    int error = 0,cnt = 0;
    unsigned long long min_tsc = (unsigned long long) -1;
    val = native_read_tsc();
    do {
        usleep(4950);
        val2 =native_read_tsc();
        diff = val2 - val;
        if (diff 0) {
            min_tsc = min_tsc diff?diff:min_tsc;
            error = 0;
            cnt ++;
        }
        if (error ++ 6) return -1;
        val = val2;
    } while(cnt 3);

    return min_tsc / 5;
}

int aperfmperf_mhz(unsigned int cpu, unsigned int tsc)
{
    unsigned long long aperf = 0, aperf2 = 0;
    unsigned long long mperf = 0, mperf2 = 0;

    if (rdmsr_on_cpu(MSR_IA32_MPERF, cpu, mperf) != 0)
        return -1;

    if (rdmsr_on_cpu(MSR_IA32_APERF, cpu, aperf) != 0)
        return -1;
    usleep(99950);
    if (rdmsr_on_cpu(MSR_IA32_MPERF, cpu, mperf2) != 0)
        return -1;

    if (rdmsr_on_cpu(MSR_IA32_APERF, cpu, aperf2) != 0)
        return -1;

    aperf = aperf2 - aperf;
    mperf = mperf2 - mperf;
    return tsc * aperf / mperf / 1000;
}

void* threadFun(void* arg)  //arg  传递线程标号(自己定义)
{
    cpu_set_t mask;  //CPU核的集合
    cpu_set_t get;   //获取在集合中的CPU
    struct perf_cpu_info *perf = (struct perf_cpu_info *)arg;

    CPU_ZERO(mask);
    CPU_SET(perf-index, mask);
    if (sched_setaffinity(0, sizeof(mask), mask) == -1)
    {
         printf("warning: could not set CPU affinity, continuing...\n");
    }
    perf-mhz = aperfmperf_mhz(perf-index, perf-tsc);
//    printf("cpu[%d] %d Mhz\n", perf-index, perf-mhz);

    return NULL;
}

int aperf_get_min_freq_mhz(int tsc)
{
    int num=0;
    int i;

    num = sysconf(_SC_NPROCESSORS_CONF);  //获取核数
    pthread_t thread[num];

    cpu_list = (struct perf_cpu_info*)malloc(num * sizeof (struct perf_cpu_info));
    for(i=0;inum;i++)
    {
        cpu_list[i].tsc = tsc;
        cpu_list[i].index = i;
        pthread_create(thread[i],NULL,threadFun,(void*)cpu_list[i]);
    }
    unsigned int min = (unsigned int)(-1);
    for(i=0; i num; i++)
    {
        pthread_join(thread[i],NULL);//等待所有的线程结束,线程为死循环所以CTRL+C结束
    }
    for(i=0; i num; i++)
    {
        min = cpu_list[i].mhz min ? cpu_list[i].mhz : min;
    }

    free(cpu_list);
    return min;
}

最新回复(0)
/jishuuFPSBHZEhpWWkRv6eAac2EcIDaIFnYvrLPkv7Q_3D_3D4794568
8 简首页