在linux中,与动态调用相关的时钟周期中程序的意外执行时间

Unexpected execution time of a program in clock cycles with respect to dynamic scalling in linux

本文关键字:时钟周期 程序 意外 执行时间 调用 linux 动态      更新时间:2023-10-16

我正在用c语言编写一个程序,以查找执行任务所需的CPU周期时间。我正在避免时间转换,时间在秒= 1/时钟周期的CPU频率变化,而低负载的服务器,以节省功耗。

程序1

  ///////////////////////// RDTSC Functions /////////////////////////
inline void start_rdtsc_rdtscp_ia64() {
    asm volatile ("CPUIDnt"
            "RDTSCnt"
            "mov %%edx, %0nt"
            "mov %%eax, %1nt": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx");
}
inline void end_rdtsc_rdtscp_ia64() {
    asm volatile("RDTSCPnt"
            "mov %%edx, %0nt"
            "mov %%eax, %1nt"
            "CPUIDnt": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx");
}
inline void warmup_rdtsc_rdtscp_ia64() {
    start_rdtsc_rdtscp_ia64();
    end_rdtsc_rdtscp_ia64();
    start_rdtsc_rdtscp_ia64();
    end_rdtsc_rdtscp_ia64();
    start_rdtsc_rdtscp_ia64();
    end_rdtsc_rdtscp_ia64();
}
inline uint64_t get_start_ia64() {
    return (((uint64_t) cycles_high << 32) | cycles_low);
}
inline uint64_t get_end_ia64() {
    return (((uint64_t) cycles_high1 << 32) | cycles_low1);
}
///////////////////////// RDTSC Timer Functions /////////////////////////
inline void start_timer() {
    warmup_rdtsc_rdtscp_ia64();
    start_rdtsc_rdtscp_ia64();
}
inline void end_timer() {
    end_rdtsc_rdtscp_ia64();
    start = get_start_ia64();
    end = get_end_ia64();
}
inline uint64_t get_cycles_count() {
    return end - start;
}
// measuring time here 
start_timer();
perform a task for length K //Let large K means more computation
end_timer();

time in ticks= get_cycles_count()

程序2

int main()
{
while(1);
}

我已经使用了warmup_rdtsc_rdtscp_ia64()函数,以便我的rdtsc和cpuid按照intel文档准备好,它需要获得正确的读取。

没有Program2,我得到更高的周期读数,我无法找到执行时间和长度k之间的原因和关系

有了Program2,我得到了预期的结果-意味着我可以将执行时间和k的长度相关联。获得更高的时钟周期执行时间和更高的长度k

我只明白,Program2阻止CPU进入省电模式,所以我的CPU总是运行到最高的CPU频率,而没有Program2我的CPU进入省电模式,以节省电力和运行到可能的最低频率。

所以,我的疑问如下

  1. 不存在Progra2时,CPU进入省电模式(CPU频率较低),以节省电量。虽然CPU运行在较低的频率,但我仍然期待几乎相似的时钟周期范围。出于同样的原因,我没有使用Time_in_sec= 1/Frequency进行转换。是什么原因我得到更高的时钟周期????

  2. 谁能解释一下-在时钟周期内完成任务所需的时间与不同频率水平(省电模式,按需模式,性能模式)之间的关系?

我正在使用Linux和gcc和g++。

我需要你的帮助来理解在不同的电源模式下完成任务所需的时钟周期之间的关系(省电模式,按需模式,性能模式)

您可以使用许多工具来实现您的目标,您应该尝试利用这些工具,而不必使用自己的工具。以下是我最喜欢的两个:

https://perf.wiki.kernel.org/index.php/Main_Page

https://code.google.com/p/likwid/

关于你的两个问题,我提供如下:完成一个程序所需的时间与CPU频率没有直接联系。许多人使用一种称为指令周期(IPC)的度量。IPC度量可以有很大的不同。在当前的机器上,at可能高达2到4,也就是说,CPU在每个CPU周期内回收多条指令,因为它可以在每个周期内发出多条指令。你在程序中看到的IPC至少取决于以下几点:CPU可以利用的指令级并行性的数量(例如,因为你可能有一个乱序处理器)和数据中的局部性的数量(例如,因为更多的局部性意味着更多的缓存命中,因此更少的内存等待)。

CPU时钟频率在现代系统上也是不同的。它可以更高或更低取决于1)省电模式(即,如果它是一台拔掉电源线的笔记本电脑)和2)当前系统负载(即,你有几个CPU,但如果它们大多数都是空闲的,一个CPU可以比四个CPU同时运行更快)。

因此,你想要的是以下三样东西:1. 程序的平均IPC2. 运行程序时的平均CPU频率3.程序中的指令数

你可以使用上面的代码计算你的执行时间。然后,您可以使用likwid或perf来调整这个低级别的性能。你可以看到省电模式对CPU频率的影响。

好运。