测试一段代码运行时间,每次不一样,求问原因

g1o2o1g 2016-10-28 11:35:50
测试程序代码如下:


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

//inline
uint64_t rdtsc()
{
unsigned long a, d;
asm volatile ("cpuid; rdtsc" : "=a" (a), "=d" (d) : : "ebx", "ecx");
return a | ((uint64_t)d << 32);
}

volatile int delay(uint64_t d_time){
int t,y,x=0;
t= d_time;
int a= 10;
int b=7;
for(;t>0;t--){
asm volatile (
"mov %1 , %%eax; mov %%eax, %0;" :
"=r" (b):
"r" (a):
"%eax");
}
return b;
}

int main(int ac, char **av)
{

int i;
uint64_t end_aes_time,end_proc_time;
uint64_t time4;
for(i =0;i<10;i++)
{
end_aes_time = rdtsc();
delay(50);
end_proc_time = rdtsc();
time4 = end_proc_time-end_aes_time;
printf("%4ld ", time4); // delay time
printf("\n");
}
return 0;
}



我想做的工作就是测试delay()函数的运行时间,使用rdtsc记录时间。测试结果却是如下:
1796
1540
1384
1380
1376
1384
1380
1380
1376
1384

结果显示,10次结果前两次时间很长,第一次时间长我觉得可以认为是cache缓存的关系,可是第二次是为什么呢?
不知道有没有人能帮我给一个合理的解释呢?是CPU的原因?还是什么别的原因呢?
而且第一次时间长,也不是很合理,按理说delay()里已经有循环了,所以cache的时候应该只有一次,也不该那么长时间。
求解啊,这个问题对我之后的实验很关键的,我要获得一个相对稳定的delay()函数。


...全文
8853 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
chaoswind 2017-06-30
  • 打赏
  • 举报
回复
晕, 前面的回答都有些片面: 1 这个的确和os调度有关,如果是轻负载情况下,可以通过多次运行消除os调度的影响; 2 最最最重要的是现在的(近10年来的)处理器都支持动态频率调整,如果负载不重会降频。这个可以去intel网站上查如何破。
g1o2o1g 2016-10-28
  • 打赏
  • 举报
回复
引用 2 楼 nswcfd 的回复:
至于怎么屏蔽,我也想知道呢
可屏蔽中断可以被屏蔽,但是还有不可屏蔽中断的存在,比如时钟中断,这是不可屏蔽的。
g1o2o1g 2016-10-28
  • 打赏
  • 举报
回复
引用 1 楼 nswcfd 的回复:
OS的调度因素,中断的因素(哪怕是rt优先级的进程),除非能全部屏蔽掉,否则测量值就是有抖动的。
中断调度的因素可以排除的,因为测量时间用的是rdtsc,这个计数器记录的是CPU每次时钟信号来就加1,一次中断调度,时间最起码是10000多时钟周期。现在的测试结果顶多只有几百的差。 我认为第一个测试数据偏大,可以是CPU读取数据时候,从内存读,之后从cache读,所以有差别,可是第二次测试数据仍旧偏大,就不知道为什么了。
nswcfd 2016-10-28
  • 打赏
  • 举报
回复
至于怎么屏蔽,我也想知道呢
nswcfd 2016-10-28
  • 打赏
  • 举报
回复
OS的调度因素,中断的因素(哪怕是rt优先级的进程),除非能全部屏蔽掉,否则测量值就是有抖动的。
g1o2o1g 2016-10-28
  • 打赏
  • 举报
回复
引用 6 楼 nswcfd 的回复:
提前执行一次delay好像也没有起到warm icache的效果,那估计跟分支预测的状态有关系。 手工把循环展开,可以消除这方面的影响。
好的,我试试。
nswcfd 2016-10-28
  • 打赏
  • 举报
回复
提前执行一次delay好像也没有起到warm icache的效果,那估计跟分支预测的状态有关系。 手工把循环展开,可以消除这方面的影响。
nswcfd 2016-10-28
  • 打赏
  • 举报
回复
之前没仔细看数据,应该没有中断的干扰。 也不是每次都是前两个大吧。 2749 2546 2552 2615 2546 2546 2546 2540 2546 2552 第一个肯定是大的,估计跟指令cache miss有关系?

1,025

社区成员

发帖
与我相关
我的任务
社区描述
Linux /Unix kernel支持不同的硬件体系,X86, ARM, MIPS, 等等
社区管理员
  • CPU和硬件区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧