x**l 发帖数: 64 | 1 【 以下文字转载自 Programming 讨论区 】
发信人: xybl (xybl), 信区: Programming
标 题: 请教:属于google不到答案的问题
发信站: BBS 未名空间站 (Wed Apr 23 21:49:44 2014, 美东)
linux下的一段代码,single thread,可以独占一个cpu 100%的资源。最主要部分就是
这个loop
for (uint32_t i = 0; i < 10; i++)
{
working(pBuf, bufferNum);
gap(gapLoops);
}
working()会做一些有business 意义的操作,
gap()就是很简单的一个双循环去制造一些时延在两次working()之间。
如果gap()只运行很短的时间,例如34个cpu clock cycles,则working()在iteration
2~10次时用的时间很短,例如,1100个cycles
如果gap()只运行较长时间,两次working()之间的时延有1个second,则working()在
iteration 2~10次的运行时间会double甚至2.5倍,例如会达到2500个cycles
我已经用numactl和chrt让这个程序充分独占一个cpu core,而且用cpuset把其他
threads移开这个core上.
我的问题是:
是什么原因导致了这种差异?
有什么debug的手段/定量地检查这种原因造成的影响?
编辑:
我知道在某些real time kernel或者一些RTOS下,没有这种差异. 但对更大型的复杂程
序则仍然有这种差异. 由于不能理解其中的原因,所以无法调制. 所以我主要想理解为
什么,而不是怎样才能避免这个差异. | x**l 发帖数: 64 | 2 sample code我放在这个link
https://onedrive.live.com/?cid=96AAD7C8AEF82405&id=96AAD7C8AEF82405!108
用这个命令可以在linux上用gcc 4.4或者更高版本build
g++ -O3 -std=c++0x -march=native -ftemplate-depth-1025 main_inline.cpp -o a_
inline_opt.out
参考启动命令分别是这样的
短时延
sudo numactl --physcpubind=3 --membind=0 ./a_inlin_opt.out 1 0
长时延
sudo numactl --physcpubind=3 --membind=0 ./a_inlin_opt.out 1 2999999999
启动后还需要用 "sudo -f -p [priority] 改变调度策略,然后按任意键继续.
谢谢大家了.
编辑:
SSA指出clock测量方法不准确,虽然最后结果还是类似,但为排除意外,我还是将
onedriver上的sample code改为
asm volatile(
"cpuid;"
"rdtsc;"
"cpuid;"
: "=a" (a), "=d" (d));
这样老一点的cpu也可以运行. | x**l 发帖数: 64 | 3 在programming贴了,在这边也碰下运气.不是简单的面试题,如果你现在忙着找工作,建
议绕道,节省时间. | s********a 发帖数: 2796 | 4 不懂,纯猜测是不是有些缓存中的变量时间过长被系统回收了?
【在 x**l 的大作中提到】 : 在programming贴了,在这边也碰下运气.不是简单的面试题,如果你现在忙着找工作,建 : 议绕道,节省时间.
| t*****s 发帖数: 416 | 5 我猜还是scheduling导致的。前者2~10个最外圈loop基本没有几率中途被schedule。
而后者1秒很可能被多次schedule。于是前者完全跑在L1 cache上后者每次都要从内存
读。
又看了眼发现你这个是用户态的程序,那你读CPU tick就更不靠谱了。用time命令更合
适。
虽然你说已经把thread全部挪走了,但是第一系统可能会自动balancing,第二可能有
kernel thread被schedule过来,第三可能会有IRQ handler跑到你的core上来。
只有把你的测试程序写成system call或者kernel module,然后在内核态里锁住当前
CPU跑才能完全保证独占CPU。
【在 x**l 的大作中提到】 : 在programming贴了,在这边也碰下运气.不是简单的面试题,如果你现在忙着找工作,建 : 议绕道,节省时间.
| P******r 发帖数: 1342 | 6 同ls
间隔一秒会有context switch. cache被清掉了 | x**l 发帖数: 64 | 7 如果你运行了我的代码就知道,schedule会被chrt改为fifo 的 10, 并make sure 这个
core上没有高于这个的thread了.
IRQ handler 通过修改 /proc/irq/* 可以mask掉, numactl决定了这个process没法再
几个core上跳来跳去.
rdtsc/rdtscp是可以在priviledge level 3运行的.
请问在kernel mode里怎么锁住当前cpu,通过numactl/cpuset?
【在 t*****s 的大作中提到】 : 我猜还是scheduling导致的。前者2~10个最外圈loop基本没有几率中途被schedule。 : 而后者1秒很可能被多次schedule。于是前者完全跑在L1 cache上后者每次都要从内存 : 读。 : 又看了眼发现你这个是用户态的程序,那你读CPU tick就更不靠谱了。用time命令更合 : 适。 : 虽然你说已经把thread全部挪走了,但是第一系统可能会自动balancing,第二可能有 : kernel thread被schedule过来,第三可能会有IRQ handler跑到你的core上来。 : 只有把你的测试程序写成system call或者kernel module,然后在内核态里锁住当前 : CPU跑才能完全保证独占CPU。
|
|