c-与单进程场景相比,多进程场景中的访问时间意外降低



我正在从program1访问一个共享库(共享数组数据结构),并找到读取该数组所有元素的访问时间。当只有Program1单独执行时,我得到了大约17000个滴答声。

现在,当我首先在另一个选项卡中执行program2(有空的while循环以防止终止)时,然后运行program1并测量读取该数组所有元素的访问时间。令我惊讶的是,与之前只有Program1执行的场景相比,现在我得到了8000个滴答声。

与有两个程序时相比,ONLY程序1执行时读取数组所需的时间更长,程序1执行的任务与前一个相同,程序2在循环时使CPU保持繁忙。当存在程序1时,预期的访问时间会更高,而实际结果则相反。

为什么会发生这种情况?

这是共享库

#include <stdio.h> 
static const int DATA[1024]={1 ,2 ,3,.....1024];
inline void foo(void)
{
int j, k=0,count=0;
for(j=0;j<1024;j++)
{
k=DATA[j];
}
k+=0;    
}

程序1

int main(void)
{    
foo();
start=timer();
foo();
end=timer();
printf("Time1=%llun",end-start);    
start=timer();
foo();
end=timer();
printf("Time2=%llun",end-start);    

start=timer();
foo();
end=timer();
printf("Time3=%llun",end-start); 
sleep(1);
start=timer();
foo();
end=timer();
printf("after sleep(1)n");
printf("Time4=%llun",end-start);    
start=timer();
foo();
end=timer();
printf("Time5=%llun",end-start);    
sleep(2); 
start=timer();
foo();
end=timer();
printf("after sleep(2)n");
printf("Time6=%llun",end-start);    
return 0;
}

程序2

int main(void)
{
while(1)
{}        
return 0;
}

CASE1(仅运行程序1)

输出

Time1=17918
Time2=17672  
Time3=17816  
after sleep(1)
**Time4= 20716 ** // Is it due to wake up from sleep mode ?
Time5=17722
after sleep(2)
**Time6=20910** // Is it due to wake up from sleep mode ?

CASE1(程序2先运行,然后程序1开始运行)

输出

Time1 =7483  
Time2=7205
Time3=7399
after sleep(1)
**Time4= 8734 ** // Is it due to wake up from sleep mode ?
Time5=7326
after sleep(2)
**Time6=9070** // Is it due to wake up from sleep mode ?

根据我的理解,当程序1单独使用CPU时,与程序1和程序2同时使用CPU相比,读取阵列所需的时间必须更短。

我在哪里犯错误?我有i7机器,只有一个核心,超线程被禁用,ASLR被禁用。

编辑1:

根据Mysticial的建议,我的CPU进入省电模式,而ONLY program1在那里,所以CPU进入节电模式,然后要将其从省电模式唤醒,需要更大的访问时间。因此,他的建议是多次访问DATA数组。

这是我修改过的共享库。程序1和程序2保持不变。

#include <stdio.h> 
static const int DATA[1024]={1 ,2 ,3,.....1024];
inline void foo(void)
{
int j, k=0,count=0;
while(count++<10000)
{  
for(j=0;j<1024;j++)
{
k=DATA[j];
}
}  
k+=0;    
}

现在输出如下

CASE1(仅运行程序1)

输出

Time1=75186246
Time2=77570299 
Time3=80548529 
after sleep(1)
**Time4= 92608363 ** // Is it due to wake up from sleep mode ?
Time5=75616487
after sleep(2)
**Time6=97021338** // Is it due to wake up from sleep mode ?

CASE1(程序2先运行,然后程序1开始运行)

输出

Time1 =139337099 
Time2=155801957
Time3=146586856
after sleep(1)
**Time4= 130558062 ** // Why lower access time after sleep mode ?
Time5=145250551 // Time5 is expected lower than Time4 as other run . Why lower here ?
after sleep(2)
**Time6=130940183** // Again Why lower access time after sleep mode ?

以下是我关于修改共享库的新问题

  1. 当没有程序2时,则睡眠后访问时间(t4/t6)比之前的访问时间(t3/t5,进入睡眠前)高。我可以说,这是由于从睡眠中唤醒CPU,正如Mysticial所解释的那样吗?

  2. 现在,随着程序2在另一个选项卡中运行,与之前的访问时间(t3/t5,进入睡眠之前)相比,睡眠后访问时间(t4/t6)更低。我的q(1)和q(2)的原因是矛盾的。从睡眠中醒来(t4<t3)后获得较低访问时间的原因是什么?虽然我在睡眠后没有多次访问DATA阵列(原始共享库)的情况下获得了更高的访问时间。

  3. 为什么t2<t1 and t3<t2不总是为true,因为共享库已经加载到内存和缓存中。是因为页面交换吗?

我在linux下使用gcc。如有任何帮助,我们将不胜感激。提前谢谢。

这是我的推测性答案,似乎已经在评论中得到了证实:

在最初的基准测试中,每个测试只运行一次迭代。因此,基准测试运行的时间不够长,无法"平均化"所有的随机性。

当您单独运行程序1时,它需要将CPU从省电状态唤醒。这需要时间,并且可能会导致运行时间更长。

当您同时运行两个程序(首先从program2开始)时,program2会提前将CPU踢出省电状态。因此,当您运行程序1时,这种预热惩罚不会实现。


一旦您循环基准测试需要更长的时间,这种预热惩罚将变得微不足道,您最终可以看到代码的预期稳态性能。(程序1本身更快)

最新更新