Redian新闻
>
请教:属于google不到答案的问题
avatar
请教:属于google不到答案的问题# Programming - 葵花宝典
C*5
1
【 以下文字转载自 Stock 讨论区 】
发信人: CRH1235 (永远的1), 信区: Stock
标 题: 国家队的策略其实非常聪明
发信站: BBS 未名空间站 (Mon Jul 6 11:51:34 2015, 美东)
就是下午两点前不管,盘尾爆拉力保翻红。散户学习起来很快的。连搞两天你还敢卖吗
?对股指期货的空头也是极大打击。股指期货毕竟是按天结算的。
这样资金消耗小。开盘指数拉高扫货盘面虽然好看,可是1200亿够几天?
avatar
s*e
2
爸妈前年来美待过三个月。去年在签证过期后一年内办了中信代签,到今年10月到期。
他们准备9月来美。
问题1:如果他们待三个月回国后,过多久可以再次申请中信代签?因为他们已经代签
过一次了,可以接着代签下去吗?(前提当然是签证过期不超过一年)
问题2:有可能帮爸妈申请绿卡,可是他们可能待补惯,不会等到绿卡下来就回国。如
果申请时人在美国,是不是办的就快, 不管人是不是在申请过程等待中在哪里?
万分感谢。
avatar
u*d
3
我去年前2个月在一公司上班,存了401K。后10个月在另一个公司上班,公司没有401K
。我可以存去年的traditional IRA $5500 吗?是tax deductible吗?
多谢答复!
avatar
n*e
4
Offer letter上写的职位是7月31号开始,但是现在学校都还没帮我申到I797。是不是
得要老板重新给我一个offer letter,这样我才能去大使馆申请H1的签证?
avatar
a*o
5
the last airbender是除了6th sense,印度导演最好的片子了吧
情节有点松散,想走LOTR路线但是功力不足。而且定位成PG,儿童片一部。不过场面还
是很好看的,比原先的期望好,原先想的是跟10000BC一样的烂片
eclipse跟new moon一样没长进,想看点风景呢,结果三个大脑袋在屏幕上晃来晃去
配角吸血鬼Jackson Rathbone这个演员倒是很活跃,昨天看eclipse他就出来唧歪半天
,没想到今天airbender又看到他
这回安心了,希望7/16的inception不让人失望
avatar
x*l
7
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下,没有这种差异. 但对更大型的复杂程
序则仍然有这种差异. 由于不能理解其中的原因,所以无法调制. 所以我主要想理解为
什么,而不是怎样才能避免这个差异.
avatar
S*I
8
存永远是可以存的,能不能抵税要看你的收入水平了。

401K

【在 u*****d 的大作中提到】
: 我去年前2个月在一公司上班,存了401K。后10个月在另一个公司上班,公司没有401K
: 。我可以存去年的traditional IRA $5500 吗?是tax deductible吗?
: 多谢答复!

avatar
S*I
9
no need

【在 n*****e 的大作中提到】
: Offer letter上写的职位是7月31号开始,但是现在学校都还没帮我申到I797。是不是
: 得要老板重新给我一个offer letter,这样我才能去大使馆申请H1的签证?

avatar
b*d
10
1000bc还不错吧。
我觉得挺好啊。

【在 a**o 的大作中提到】
: the last airbender是除了6th sense,印度导演最好的片子了吧
: 情节有点松散,想走LOTR路线但是功力不足。而且定位成PG,儿童片一部。不过场面还
: 是很好看的,比原先的期望好,原先想的是跟10000BC一样的烂片
: eclipse跟new moon一样没长进,想看点风景呢,结果三个大脑袋在屏幕上晃来晃去
: 配角吸血鬼Jackson Rathbone这个演员倒是很活跃,昨天看eclipse他就出来唧歪半天
: ,没想到今天airbender又看到他
: 这回安心了,希望7/16的inception不让人失望

avatar
b*d
11
这哥们就是不说这些话也没戏。肯尼迪当年要用天主教版的圣经宣誓都惹出了轩然大波
,更别说摩门了。
avatar
x*u
12
这是操作系统原理的基本问题。。。

iteration

【在 x**l 的大作中提到】
: 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

avatar
u*d
13
谢谢回复。所以即使我去年在上个公司存了401k,在现在的公司没存,然后收入在一定
范围内,我存的traditional IRA 本金就可以减税?因为看到存 traditional 的条件
之一是没存公司的401K,所以比较迷惑。到底我这样的情况是符合条件还是不?
avatar
n*e
14
那就是用原来的offer letter就可以了?

【在 S**I 的大作中提到】
: no need
avatar
E*m
15
他有他的其他問題,不過摩門好像漸漸被接受了,Glenn Beck這種
渾人都有那麼多粉絲。

【在 b*********d 的大作中提到】
: 这哥们就是不说这些话也没戏。肯尼迪当年要用天主教版的圣经宣誓都惹出了轩然大波
: ,更别说摩门了。

avatar
x*l
16
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] 改变调度策略,然后按任意键继续.
谢谢大家了.
avatar
S*I
17
Modified AGI不超过59000就可以抵税,超过的话能抵税的部分随MAGI的增加而减少,
AMGI超过69000就完全不能抵税了。

【在 u*****d 的大作中提到】
: 谢谢回复。所以即使我去年在上个公司存了401k,在现在的公司没存,然后收入在一定
: 范围内,我存的traditional IRA 本金就可以减税?因为看到存 traditional 的条件
: 之一是没存公司的401K,所以比较迷惑。到底我这样的情况是符合条件还是不?

avatar
S*I
18
yes

【在 n*****e 的大作中提到】
: 那就是用原来的offer letter就可以了?
avatar
p*t
19
他本人其实并不是很虔诚,自己在采访中也承认过,所以大部分摩门教徒还是更prefer
Mitt Romney.
我看他退出是迟早的事情。

【在 E*****m 的大作中提到】
: 他有他的其他問題,不過摩門好像漸漸被接受了,Glenn Beck這種
: 渾人都有那麼多粉絲。

avatar
x*l
20
谢谢,没错,大方向容易理解,现在缺少的是具体的细节原因.

【在 x****u 的大作中提到】
: 这是操作系统原理的基本问题。。。
:
: iteration

avatar
S*L
21
说这种话是两边不讨好吧.
Glenn Beck是右到底的小丑, 当然能有粉丝.
avatar
x*u
22
你这个有business意义的事情,应该不是单纯的CPU能罩得住的计算吧。

a_

【在 x**l 的大作中提到】
: 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

avatar
e*n
23
这种走中间路线的调调是在竞选副总统候选人
avatar
x*l
24
是很简单的运算, 一些 memory copy 加整数运算和branch 跳转. 没有任何system
call 和lib function.
sample 代码在那里,void translate().
你可以自己改成任何简单的代码逻辑, 不能是浮点运算或者其它任何涉及到进入kernel
mode的调用.

【在 x****u 的大作中提到】
: 你这个有business意义的事情,应该不是单纯的CPU能罩得住的计算吧。
:
: a_

avatar
x*u
25
那把这段代码直接改为驱动不就完事了?

kernel

【在 x**l 的大作中提到】
: 是很简单的运算, 一些 memory copy 加整数运算和branch 跳转. 没有任何system
: call 和lib function.
: sample 代码在那里,void translate().
: 你可以自己改成任何简单的代码逻辑, 不能是浮点运算或者其它任何涉及到进入kernel
: mode的调用.

avatar
x*l
26
为什么改成driver就可以?
如果是driver,它的scheduling policy是由user space的caller process决定的.
如果是kernel process, no way we can control the core on which it is running.
by no means moving it to driver could solve it.

【在 x****u 的大作中提到】
: 那把这段代码直接改为驱动不就完事了?
:
: kernel

avatar
x*u
27
用户态下你可以控制policy,不过比policy级别高的东西多了。
内核态你可以独占CPU任意长时间,不过这都是有代价的。。。

running.

【在 x**l 的大作中提到】
: 为什么改成driver就可以?
: 如果是driver,它的scheduling policy是由user space的caller process决定的.
: 如果是kernel process, no way we can control the core on which it is running.
: by no means moving it to driver could solve it.

avatar
x*l
28
请问比user space 下的policy 级别高的有哪些? 能给个link吗?

【在 x****u 的大作中提到】
: 用户态下你可以控制policy,不过比policy级别高的东西多了。
: 内核态你可以独占CPU任意长时间,不过这都是有代价的。。。
:
: running.

avatar
x*u
29
比如抢占啊,中断啊。
就算你设了CPU亲和度也不是绝对的。

【在 x**l 的大作中提到】
: 请问比user space 下的policy 级别高的有哪些? 能给个link吗?
avatar
x*l
30
interrupt shield可以让interrup只route到特定的几个core上去.而避免使用另外一些
core.
抢占应该是严格按照schduling policy 来的.

【在 x****u 的大作中提到】
: 比如抢占啊,中断啊。
: 就算你设了CPU亲和度也不是绝对的。

avatar
x*u
31
你用的命令做不到啊。

【在 x**l 的大作中提到】
: interrupt shield可以让interrup只route到特定的几个core上去.而避免使用另外一些
: core.
: 抢占应该是严格按照schduling policy 来的.

avatar
x*l
32
即使enable interrupt shield也不能解决问题. interrupt sheild 可以通过
/proc/irq/default_smp_affinity修改.
而且就算是interrupt造成的影响, 但不能解释为什么会对working()有影响.
在1 sec 延迟情况下, interrupt99%会落在运行gap()时,而不是运行working()时.
就算interrupt落在working()运行时,也不能解释为什么8个working() call都会受完全
一致的影响.

【在 x****u 的大作中提到】
: 你用的命令做不到啊。
avatar
x*u
33
这些东西不是为了实时系统设计的,你不应该在普通Linux上做RTOS的事情啊。

【在 x**l 的大作中提到】
: 即使enable interrupt shield也不能解决问题. interrupt sheild 可以通过
: /proc/irq/default_smp_affinity修改.
: 而且就算是interrupt造成的影响, 但不能解释为什么会对working()有影响.
: 在1 sec 延迟情况下, interrupt99%会落在运行gap()时,而不是运行working()时.
: 就算interrupt落在working()运行时,也不能解释为什么8个working() call都会受完全
: 一致的影响.

avatar
x*l
34
我知道在某些real time kernel或者一些RTOS下,没有这种差异. 但对更大型的复杂程
序,在RT kernel下则仍然有这种差异. 由于不能理解其中的原因,所以无法调制. 所以
我主要想理解为什么,而不是怎样为这个小程序避免这个差异.

【在 x****u 的大作中提到】
: 这些东西不是为了实时系统设计的,你不应该在普通Linux上做RTOS的事情啊。
avatar
x*u
35
就是任务切换了啊。

【在 x**l 的大作中提到】
: 我知道在某些real time kernel或者一些RTOS下,没有这种差异. 但对更大型的复杂程
: 序,在RT kernel下则仍然有这种差异. 由于不能理解其中的原因,所以无法调制. 所以
: 我主要想理解为什么,而不是怎样为这个小程序避免这个差异.

avatar
x*k
36
没有任务切换,100%CPU独占,无浮点,无sys call,only one thread on the core.
interrupt shield,

【在 x****u 的大作中提到】
: 就是任务切换了啊。
avatar
x*u
37
没任务切换,跑完进程你的CPU就死掉了。

core.

【在 x****k 的大作中提到】
: 没有任务切换,100%CPU独占,无浮点,无sys call,only one thread on the core.
: interrupt shield,

avatar
x*k
38
什么叫CPU死掉?至少我测试时系统没有freeze,任务切换只发生在其他thread上,不
会抢占这个ctritical的thread

【在 x****u 的大作中提到】
: 没任务切换,跑完进程你的CPU就死掉了。
:
: core.

avatar
x*u
39
俗称跑飞了

【在 x****k 的大作中提到】
: 什么叫CPU死掉?至少我测试时系统没有freeze,任务切换只发生在其他thread上,不
: 会抢占这个ctritical的thread

avatar
x*k
40
我的情况不属于跑飞了

【在 x****u 的大作中提到】
: 俗称跑飞了
avatar
S*A
41
这个不属于跑飞了,跑飞了是指 PC (EIP) 指到代码段以外的地方去了。
你的程序我的 core 2 due 跑不了, illegal instruction。 应该就是
那个 rdtscp 的汇编指令。rdtscp 是 i7 才引入的。
avatar
S*A
42
我想我知道你描述的问题了。
rdtscp 不是 full serialize instruction.
你去读一下 Intel 手册, rdtscp 保证读 TSC 的时候前面
的全部 instruction 都运行完了。 但是不保证没有开始运行
后面的 instruction. 因为 Intel 的 CPU 是 out of order
execution。 你相当与把 rdtscp 后面的循环也算到 work()
里面了。
建议你读一下 Intel 的这个文档,特别是第 16 页关于 rdtscp
的误差。你应该用 CPUID 来 full serialize instruction。
http://www.intel.com/content/www/us/en/intelligent-systems/embe
avatar
x*u
43
楼主说
“我知道在某些real time kernel或者一些RTOS下,没有这种差异. 但对更大型的复杂程
序,在RT kernel下则仍然有这种差异.”

【在 S*A 的大作中提到】
: 我想我知道你描述的问题了。
: rdtscp 不是 full serialize instruction.
: 你去读一下 Intel 手册, rdtscp 保证读 TSC 的时候前面
: 的全部 instruction 都运行完了。 但是不保证没有开始运行
: 后面的 instruction. 因为 Intel 的 CPU 是 out of order
: execution。 你相当与把 rdtscp 后面的循环也算到 work()
: 里面了。
: 建议你读一下 Intel 的这个文档,特别是第 16 页关于 rdtscp
: 的误差。你应该用 CPUID 来 full serialize instruction。
: http://www.intel.com/content/www/us/en/intelligent-systems/embe

avatar
S*A
44
这个程序测量 TSC 的方法就是错的,无论什么 OS 都需要改过来再说,
不然结果没有意义。如果 RTOS 频繁中断或者中断里面有 serialize
instruction 完全有可能使结果看上去更接近。

杂程

【在 x****u 的大作中提到】
: 楼主说
: “我知道在某些real time kernel或者一些RTOS下,没有这种差异. 但对更大型的复杂程
: 序,在RT kernel下则仍然有这种差异.”

avatar
x*l
45
谢谢回复
测量方式是存在误差,绝对不会产生大于1000个clocks级别的误差,xeon上
instruction pipeline不会超过50级,instruction虽然execution out-of-order, 但
进pipeline(IF)和最后的WB肯定是按序的,所以不会超过50 clocks的误差
当然,为了让结果更准确,可以把rdtsc部分改成这样,这样你应该可以compile了。
asm volatile(
"cpuid;"
"rdtsc;"
"cpuid;"
: "=a" (a), "=d" (d));
即使把代码改成这样,最终结果应该不会有太大变化
而且即使考虑中断或者ISR中的serialize instruction.在两种运行情况下对working()
的影响应该是近似的,而不应该产生1100 vs 2500 clocks的差别。

【在 S*A 的大作中提到】
: 这个程序测量 TSC 的方法就是错的,无论什么 OS 都需要改过来再说,
: 不然结果没有意义。如果 RTOS 频繁中断或者中断里面有 serialize
: instruction 完全有可能使结果看上去更接近。
:
: 杂程

avatar
G*f
46
simple cache miss ? what's being used in working could be pushed out of
cache during gap.

iteration

【在 x**l 的大作中提到】
: 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

avatar
x*l
47
cache missing. tlb missing 都只是可能. 问题在于是什么造成cache或者tlb的内容
被evicted了.整个core只有一个thread, L1i/L1d和tlb都是per core独有的.

【在 G********f 的大作中提到】
: simple cache miss ? what's being used in working could be pushed out of
: cache during gap.
:
: iteration

avatar
G*f
48
what about L2 ?

【在 x**l 的大作中提到】
: cache missing. tlb missing 都只是可能. 问题在于是什么造成cache或者tlb的内容
: 被evicted了.整个core只有一个thread, L1i/L1d和tlb都是per core独有的.

avatar
x*l
49
我专门把code和data size限制小于L1 size. 32K byte

【在 G********f 的大作中提到】
: what about L2 ?
avatar
S*A
50

你自己跑过你这样的测量程序吗,肯定没有吧。我随便看一眼你这段修改过
嵌入汇编就有至少2处影响结果的错误。要不你先改好了先测一下吧。
这个就留给你做功课了。
关于 out of order, 你知道 Intel 内部是翻译成完全不同的 micro code
执行的吧?连 register 都是 remap 过的。 所以你说绝对不会产生 1000
clocks 级别的误差从那里来的,有 Intel 官方的出处吗?
我只是很奇怪你为什么不先修正了你的程序再讨论。
[ssa]$ sudo ./a.out 1 0
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 36993 clock cycles, gap: 407 clock cycles, dummy:0.
working time: 1496 clock cycles, gap: 253 clock cycles, dummy:0.
working time: 1408 clock cycles, gap: 253 clock cycles, dummy:0.
working time: 1430 clock cycles, gap: 242 clock cycles, dummy:0.
working time: 23584 clock cycles, gap: 242 clock cycles, dummy:0.
working time: 3069 clock cycles, gap: 253 clock cycles, dummy:0.
working time: 1408 clock cycles, gap: 253 clock cycles, dummy:0.
working time: 1419 clock cycles, gap: 253 clock cycles, dummy:0.
working time: 1397 clock cycles, gap: 242 clock cycles, dummy:0.
working time: 1430 clock cycles, gap: 253 clock cycles, dummy:0.
[ssa] $ sudo ./a.out 1 299999
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 31284 clock cycles, gap: 352 clock cycles, dummy:0.
working time: 2101 clock cycles, gap: 374 clock cycles, dummy:0.
working time: 2002 clock cycles, gap: 341 clock cycles, dummy:0.
working time: 1958 clock cycles, gap: 363 clock cycles, dummy:0.
working time: 1947 clock cycles, gap: 341 clock cycles, dummy:0.
working time: 1947 clock cycles, gap: 605 clock cycles, dummy:0.
working time: 1958 clock cycles, gap: 341 clock cycles, dummy:0.
working time: 1958 clock cycles, gap: 594 clock cycles, dummy:0.
working time: 1947 clock cycles, gap: 341 clock cycles, dummy:0.
working time: 1947 clock cycles, gap: 605 clock cycles, dummy:0.
[ssa]$ sudo ./a.out 1 2999999999
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 39468 clock cycles, gap: 473 clock cycles, dummy:0.
working time: 2827 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2574 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2563 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2563 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2563 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2563 clock cycles, gap: 451 clock cycles, dummy:0.
working time: 2563 clock cycles, gap: 473 clock cycles, dummy:0.
working time: 2574 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2574 clock cycles, gap: 451 clock cycles, dummy:0.
$ sudo ./a.out 1 0
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 39017 clock cycles, gap: 748 clock cycles, dummy:0.
working time: 2926 clock cycles, gap: 451 clock cycles, dummy:0.
working time: 2596 clock cycles, gap: 737 clock cycles, dummy:0.
working time: 2607 clock cycles, gap: 451 clock cycles, dummy:0.
working time: 2596 clock cycles, gap: 792 clock cycles, dummy:0.
working time: 2596 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2629 clock cycles, gap: 726 clock cycles, dummy:0.
working time: 2596 clock cycles, gap: 462 clock cycles, dummy:0.
working time: 2596 clock cycles, gap: 737 clock cycles, dummy:0.
working time: 2607 clock cycles, gap: 451 clock cycles, dummy:0.
没有你说的差别那么大。 而且 run to run 的 variance 变化比较大,
后面一个 run 长循环和短循环是完全没有区别的。

【在 x**l 的大作中提到】
: 谢谢回复
: 测量方式是存在误差,绝对不会产生大于1000个clocks级别的误差,xeon上
: instruction pipeline不会超过50级,instruction虽然execution out-of-order, 但
: 进pipeline(IF)和最后的WB肯定是按序的,所以不会超过50 clocks的误差
: 当然,为了让结果更准确,可以把rdtsc部分改成这样,这样你应该可以compile了。
: asm volatile(
: "cpuid;"
: "rdtsc;"
: "cpuid;"
: : "=a" (a), "=d" (d));

avatar
z*n
51
手机操作系统现在至少是soft real time的,你也可以去MobileDevelopment版交流讨论
到此一挖墙

iteration

【在 x**l 的大作中提到】
: 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

avatar
S*A
52
这个程序有汇编,手机那个 rdtsp 的指令是跑不了的。

讨论

【在 z*******n 的大作中提到】
: 手机操作系统现在至少是soft real time的,你也可以去MobileDevelopment版交流讨论
: 到此一挖墙
:
: iteration

avatar
z*n
53
基本概念 代码无关

【在 S*A 的大作中提到】
: 这个程序有汇编,手机那个 rdtsp 的指令是跑不了的。
:
: 讨论

avatar
S*A
54
没有代码你如何在你的手机上实验验证是不是个
问题?理论探讨一下手机上会有什么结果然后
理论上辩论一番?
LZ 碰到这个问题根本就是 tight 在 x86 平台上的。
而且这个问题很可能本来就不是个问题。

【在 z*******n 的大作中提到】
: 基本概念 代码无关
avatar
z*n
55
看你回复了这么多,你讲讲interrupt吧

【在 S*A 的大作中提到】
: 没有代码你如何在你的手机上实验验证是不是个
: 问题?理论探讨一下手机上会有什么结果然后
: 理论上辩论一番?
: LZ 碰到这个问题根本就是 tight 在 x86 平台上的。
: 而且这个问题很可能本来就不是个问题。

avatar
x*l
56
谢谢你指出错误,匆忙之中修改的,没有测试.
如果你的CPU不支持 rdtscp,请使用这个function
typedef unsigned long long ticks;
static __inline__ ticks getticks(void)
{
unsigned a, d;
asm volatile(
"rdtsc;"
: "=a" (a), "=d" (d)
:
: "memory");
asm volatile("cpuid"
:
:
: "%eax", "%ebx", "%ecx", "%edx");
return ((ticks)a) | (((ticks)d) << 32);
}
你没有用numactl去调用,所以即使修改了代码,结果也不准确。
这是我的sample 输出
$ sudo numactl --physcpubind=3 --membind=0 ./a_inline_opt.out 1 0
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 40812 clock cycles, gap: 1224 clock cycles, dummy:0, isFound:0.
working time: 1972 clock cycles, gap: 340 clock cycles, dummy:0, isFound:0.
working time: 1408 clock cycles, gap: 332 clock cycles, dummy:0, isFound:0.
working time: 1404 clock cycles, gap: 340 clock cycles, dummy:0, isFound:0.
working time: 1408 clock cycles, gap: 344 clock cycles, dummy:0, isFound:0.
working time: 1420 clock cycles, gap: 344 clock cycles, dummy:0, isFound:0.
working time: 1416 clock cycles, gap: 336 clock cycles, dummy:0, isFound:0.
working time: 1412 clock cycles, gap: 336 clock cycles, dummy:0, isFound:0.
working time: 1404 clock cycles, gap: 340 clock cycles, dummy:0, isFound:0.
working time: 1412 clock cycles, gap: 344 clock cycles, dummy:0, isFound:0.
$ sudo numactl --physcpubind=3 --membind=0 ./a_inline_opt.out 1 999999999
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 35072 clock cycles, gap: 1001922056 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 3336 clock cycles, gap: 1001890144 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2648 clock cycles, gap: 1001806484 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2392 clock cycles, gap: 1001846708 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2316 clock cycles, gap: 1001847392 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2320 clock cycles, gap: 1001764560 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2124 clock cycles, gap: 1001793148 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2144 clock cycles, gap: 1001742628 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2048 clock cycles, gap: 1001768928 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2140 clock cycles, gap: 1001755064 clock cycles, dummy:
1937409509842606368, isFound:0.
用numctl启动命令后,需要用chrt改变scheduling
sudo chrt -f -p 10 $(ps -eF | grep "a_inline" | grep -vE "sudo|grep" | sed
-nr 's/root +([0-9]+).*/1/p')
当gap()的loop数为0时,如果还使用rdtsp来获得clk #,其所花的时间为40clocks,加
入用cpuid后,这个时间变为大约340clock
对于有较新intel cpu的同学,可以使用rdtsp来或者clock,因为working()和gap()
是在一个简单循环里执行的,所以就算rdtscp后边的指令调到它前面执行了,在计算
time difference是会被相减消除掉,下面是我使用rdtscp的sample output
$ sudo numactl --physcpubind=3 --membind=0 ./a_inline_opt.out 1 0
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 12288 clock cycles, gap: 100 clock cycles, dummy:0, isFound:0.
working time: 1400 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1164 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1160 clock cycles, gap: 44 clock cycles, dummy:0, isFound:0.
working time: 1132 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1136 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1144 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1136 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
working time: 1136 clock cycles, gap: 44 clock cycles, dummy:0, isFound:0.
working time: 1136 clock cycles, gap: 40 clock cycles, dummy:0, isFound:0.
$ sudo numactl --physcpubind=3 --membind=0 ./a_inline_opt.out 1 999999999
allocate [email protected]
memory lock is enabled.
Please run "sudo chrt -f -p [priority] " to change scheduling policy,
then press any key to continue.
Num of buffers: 1, size of each buffer: 256*8=2048 bytes, repeat 1 times,
testing.....
working time: 11428 clock cycles, gap: 1001929868 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 3464 clock cycles, gap: 1001934524 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2092 clock cycles, gap: 1001929608 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 2152 clock cycles, gap: 1001879780 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1984 clock cycles, gap: 1001909656 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1596 clock cycles, gap: 1001894788 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1996 clock cycles, gap: 1001942808 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1596 clock cycles, gap: 1001894892 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1924 clock cycles, gap: 1001912108 clock cycles, dummy:
1937409509842606368, isFound:0.
working time: 1964 clock cycles, gap: 1001848472 clock cycles, dummy:
1937409509842606368, isFound:0.

【在 S*A 的大作中提到】
: 没有代码你如何在你的手机上实验验证是不是个
: 问题?理论探讨一下手机上会有什么结果然后
: 理论上辩论一番?
: LZ 碰到这个问题根本就是 tight 在 x86 平台上的。
: 而且这个问题很可能本来就不是个问题。

avatar
x*l
57
关于不超过1000 clock误差,主要是基于对架构的理解。
x86的instruction是非等长的cisc指令,在内部会翻译成等长指令执行。但不管怎样变
,内部始终是基于pipeline的,在没有pipeline stallment情况下,pipeline入口和出
口肯定是按序的,所以无论后面的instruction跳到前面执行,也限制在pipeline的长
度内。
我记得网上有review关于intel的sandy bridge,提到了pipeline的级数,不会超过50。
回到我的代码,就算rdtscp被后面的instruction 插了,在这个简单循环中,最后的
clock数是靠将两次rdtscp的结果相减获得的,所以误差会相互抵消.
avatar
k*g
58
Sorry didn't read the whole thing. Too much details for me to understand at
7:15AM.
Some places to check.
(1) Did you disable the BIOS clock-frequency and time-sharing options?
Specifically:
--- Intel EIST, Enhanced SpeedStep
http://www.intel.com/cd/channel/reseller/asmo-na/eng/203838.htm
--- Intel Turbo Boost
http://www.intel.com/content/www/us/en/architecture-and-technol
--- Intel HyperThreading
http://www.intel.com/content/www/us/en/architecture-and-technol
These "trio" can affect CPU frequency and various performance measurement.
When doing measurements that need to be repeatable (reproducible), it is
recommended to disable all three, and re-enable when the test is done.
Second possibility:
The branch prediction table may be somehow "expired". It doesn't actually "
expire" based on time, but maybe some other threads (from other applications
) has populated the branch prediction table, thus evicting your program's
predictions from it.
Just my two guesses.
avatar
S*A
59
FT,还是错的。请接着改。
请问你是在 Intel 工作吗?你能用 Intel 内部结构去
推断 CPU 的行为而忽视 Intel 手册。
如果你对 1000 cycle 的误差感兴趣,
为什么你不按照 Intel 建议的方式使用 rdtsc 和 rdtscp?
你前面根本没有给出如何用 numctl 所以没有人能重复你的实验。
再说了,你即使用了 process scheduling, 你还是不能避免
non maskable interrupt。所以用了也是白用,你在 user space
是不能保证独占 CPU 的。
用你自己的话说,即使有少量 Interrupt/scheduling, 如何
解释我的两个 run 分布那么均匀?特别是没有循环的那个
Interrupt/scheduling 应该完全没有 Hit 到。那有循环那个
结果一样,应该也是没有 hit 到。不然你如何解释我的实验
结果,即使不改 scheduler ?

【在 x**l 的大作中提到】
: 谢谢你指出错误,匆忙之中修改的,没有测试.
: 如果你的CPU不支持 rdtscp,请使用这个function
: typedef unsigned long long ticks;
: static __inline__ ticks getticks(void)
: {
: unsigned a, d;
: asm volatile(
: "rdtsc;"
: : "=a" (a), "=d" (d)
: :

avatar
S*A
60
所以我很迷惑,你似乎知道很多内部细节,但是你又忽律
很多重要的技术细节。你不按照 Intel 建议的方式来测量,
然后抱怨有意想不到的结果。
你现在还是没有论据支持你的1000 cycle 的说法。我对 Intel
CPU 还算比较了解也不敢按照你那样乱推测。我感觉你的
测量就没有可靠性。
就算我退一步,按照你的思路,50个pipeline,先假设
Intel CPU 里面就是这样工作的。你的论据也不成立。
rdtsc 单单一个 instruction 就有 250-300 cycle。
你只要pipelien 里面有 4 个 rdtsc 那样的 instruction,
你的误差就有 1000 cycle 了。 50 个 pipeline 里面
出现 4 个 rdtscp 还是有可能的吧,特别是对空循环
的例子。
你不按照 Intel 建议的方式就没有什么信服力。
而且我的反例也有了。

50。

【在 x**l 的大作中提到】
: 关于不超过1000 clock误差,主要是基于对架构的理解。
: x86的instruction是非等长的cisc指令,在内部会翻译成等长指令执行。但不管怎样变
: ,内部始终是基于pipeline的,在没有pipeline stallment情况下,pipeline入口和出
: 口肯定是按序的,所以无论后面的instruction跳到前面执行,也限制在pipeline的长
: 度内。
: 我记得网上有review关于intel的sandy bridge,提到了pipeline的级数,不会超过50。
: 回到我的代码,就算rdtscp被后面的instruction 插了,在这个简单循环中,最后的
: clock数是靠将两次rdtscp的结果相减获得的,所以误差会相互抵消.

avatar
z*n
61
nmi smi 是经常发生的?因噎废食?

【在 S*A 的大作中提到】
: FT,还是错的。请接着改。
: 请问你是在 Intel 工作吗?你能用 Intel 内部结构去
: 推断 CPU 的行为而忽视 Intel 手册。
: 如果你对 1000 cycle 的误差感兴趣,
: 为什么你不按照 Intel 建议的方式使用 rdtsc 和 rdtscp?
: 你前面根本没有给出如何用 numctl 所以没有人能重复你的实验。
: 再说了,你即使用了 process scheduling, 你还是不能避免
: non maskable interrupt。所以用了也是白用,你在 user space
: 是不能保证独占 CPU 的。
: 用你自己的话说,即使有少量 Interrupt/scheduling, 如何

avatar
S*A
62
请问你去编译运行了 LZ 的程序了吗?
你知道他的嵌入汇编有什么错误吗? 包括 rdtscp 的版本,
现在还有。这个测量结果就不是那么信服。
又退一步来说,如果你认为 nmi 什么的可以忽律,
那同样道理 scheduling method 就可忽律。
那么我的更正的程序的结果就有说服力了。
我的程序修正了读 TSC 的 bug, 测量出没有这种差别。
至少差别是在 variance 里面的。

【在 z*******n 的大作中提到】
: nmi smi 是经常发生的?因噎废食?
avatar
z*n
63
你不是爱读intel的文档吗
这有一个
http://www.intel.com/content/dam/www/public/us/en/documents/whi

【在 S*A 的大作中提到】
: 请问你去编译运行了 LZ 的程序了吗?
: 你知道他的嵌入汇编有什么错误吗? 包括 rdtscp 的版本,
: 现在还有。这个测量结果就不是那么信服。
: 又退一步来说,如果你认为 nmi 什么的可以忽律,
: 那同样道理 scheduling method 就可忽律。
: 那么我的更正的程序的结果就有说服力了。
: 我的程序修正了读 TSC 的 bug, 测量出没有这种差别。
: 至少差别是在 variance 里面的。

avatar
S*A
65
BTW, 没有人喜欢读文档的。我也不例外。但是
如果要用起来那也没有办法。
avatar
z*n
66
你读了吗,做测量首先考虑的就是context switching

【在 S*A 的大作中提到】
: BTW, 没有人喜欢读文档的。我也不例外。但是
: 如果要用起来那也没有办法。

avatar
S*A
67
废话,所以人家示范的那个程序是在 kernel mode 实现的。
那里是用 user space 实现的。1000 cycle 根本就不够 schedule
两次,所以那个调整 scheduler 就是 distraction。 LZ 应该
先把读 TSC 代码里的 bug 修理好,做好测量再讨论。

【在 z*******n 的大作中提到】
: 你读了吗,做测量首先考虑的就是context switching
avatar
z*n
68
一个system call 就到kernel去了 spinlock是内核才可以用?

【在 S*A 的大作中提到】
: 废话,所以人家示范的那个程序是在 kernel mode 实现的。
: 那里是用 user space 实现的。1000 cycle 根本就不够 schedule
: 两次,所以那个调整 scheduler 就是 distraction。 LZ 应该
: 先把读 TSC 代码里的 bug 修理好,做好测量再讨论。

avatar
S*A
69
不明白你问这个和原来的问题有什么关系。
楼太歪了。

【在 z*******n 的大作中提到】
: 一个system call 就到kernel去了 spinlock是内核才可以用?
avatar
z*n
70
你基础知识太差 是cs专业的么

【在 S*A 的大作中提到】
: 不明白你问这个和原来的问题有什么关系。
: 楼太歪了。

avatar
S*A
71
是吗,你是刚学 system call 和 spinlock 一定什么
东西都要扯上吗?
我只是觉得这个 1000 cycle 的差别和 system call
和 spinlock 关系不大。
请你这个 CS 专业的来示范一下如何用 system call
和 spinlock 解释这个 1000 cycle 的差别,让我们
看看是不是很牵强。

【在 z*******n 的大作中提到】
: 你基础知识太差 是cs专业的么
avatar
x*l
72

FT,还是错的。请接着改。
---我改为两个lfence夹一个rdtsc,如果你还觉得不正确,麻烦你明示你认为正确的办法.
+++++++++++++
请问你是在 Intel 工作吗?你能用 Intel 内部结构去
推断 CPU 的行为而忽视 Intel 手册。
如果你对 1000 cycle 的误差感兴趣,
为什么你不按照 Intel 建议的方式使用 rdtsc 和 rdtscp?
----我始终不认为这1000个cycle是由于rdtscp/rdtsc造成的,道理很简单,最终计算的
是两次clock值的difference,而不是绝对值,在一个working()和gap()交替执行的循环
中,不管out-of-order execution怎么跳,rdtsc测测了误差都不会造成一种是working()
的时间是
1100左右, 1100左右, 1100左右,1100左右,1100左右,...
另一种是
2500左右, 2500左右, 2500左右, 2500左右, 2500左右, ....
++++++++++++++++++++++++++++++++++++
你前面根本没有给出如何用 numctl 所以没有人能重复你的实验。
再说了,你即使用了 process scheduling, 你还是不能避免
non maskable interrupt。所以用了也是白用,你在 user space
是不能保证独占 CPU 的。
-----我的测试环境设置太多,我拣最重要的一些写的,在3楼我写了启动方式,我的实际
做法要做的话包括这些
1. 至少有2个core的cpu.假设core 0和1. 我的测试的环境远比这个好,但我觉得2个
core可以说明问题了
2. 主流的linux distro, 我是rhel 2.6.32-220.4.1, redhat应该把32后面的一些
patch和functionality也merge进来了,至少要支持cpuset.
3. 建立一个cpuset,假设path为/dev/cpuset/system/, 包含core 0.
将所有的threads全部移到这个cpuset下.
4. 建另外一个cpuset, 假设path为/dev/cpuset/test/, 包含core 1
5. 修改/proc/irq/* 下的设置, shield interrupt from core 1.
6. 将当前的console的thread从system移到 /dev/cpuset/test/, 使用numactl启动程
序.
sudo numactl --physcpubind=1 --membind=0 ./a_inlin_opt.out 1 0
sudo numactl --physcpubind=1 --membind=0 ./a_inlin_opt.out 1 2999999999
7. 启动后到第二个console,用chrt修改scheduling policy.例如这个命令
sudo chrt -f -p 10 $(ps -eF | grep "a_inline" | grep -vE "sudo|grep" | sed
-nr 's/root +([0-9]+).*/1/p')
8. 严格的话,还要将那个在test cpuset下的console的thread移回system cpuset.
9. 回到最初的console,敲任意键运行.
+++++++++++++++++++++++++++++
用你自己的话说,即使有少量 Interrupt/scheduling, 如何
解释我的两个 run 分布那么均匀?特别是没有循环的那个
Interrupt/scheduling 应该完全没有 Hit 到。那有循环那个
结果一样,应该也是没有 hit 到。不然你如何解释我的实验
结果,即使不改 scheduler ?
----------没在你的机器上调试, 我真没办法解释为什么为什么你的两次run的分布
那么均匀.你用的是virtual machine吗?
我不用numactl,不改schedule policy,也可以看到类似的效应(working()花了两倍甚至
2.5倍的时间),但volatility会大一些.在家没有机器可以跑,所以结果没办法paste结果
上来.
++++++++++++++++++++++++++++++++++

【在 S*A 的大作中提到】
: FT,还是错的。请接着改。
: 请问你是在 Intel 工作吗?你能用 Intel 内部结构去
: 推断 CPU 的行为而忽视 Intel 手册。
: 如果你对 1000 cycle 的误差感兴趣,
: 为什么你不按照 Intel 建议的方式使用 rdtsc 和 rdtscp?
: 你前面根本没有给出如何用 numctl 所以没有人能重复你的实验。
: 再说了,你即使用了 process scheduling, 你还是不能避免
: non maskable interrupt。所以用了也是白用,你在 user space
: 是不能保证独占 CPU 的。
: 用你自己的话说,即使有少量 Interrupt/scheduling, 如何

avatar
x*l
73

所以我很迷惑,你似乎知道很多内部细节,但是你又忽律
很多重要的技术细节。你不按照 Intel 建议的方式来测量,
然后抱怨有意想不到的结果。
你现在还是没有论据支持你的1000 cycle 的说法。我对 Intel
CPU 还算比较了解也不敢按照你那样乱推测。我感觉你的
测量就没有可靠性。
----关于测量问题我刚给你回了,请看一下,谢谢
+++++++++++
就算我退一步,按照你的思路,50个pipeline,先假设
Intel CPU 里面就是这样工作的。你的论据也不成立。
rdtsc 单单一个 instruction 就有 250-300 cycle。
你只要pipelien 里面有 4 个 rdtsc 那样的 instruction,
你的误差就有 1000 cycle 了。 50 个 pipeline 里面
出现 4 个 rdtscp 还是有可能的吧,特别是对空循环
的例子。
----不知道你的rdtsc需要250~300cycle是从哪里来的?有reference没有?还是自己测的?
如果我们定义x86指令在pipeline中要占多少级为指令所花的时间,可以重复调用(不是
循环调用,unroll loop)这个函数,把前后两次调用的返值的different算一下就可以了
typedef unsigned long long ticks;
static __inline__ ticks getticks(void)
{
unsigned a, d;
asm volatile(
"rdtscp;"
: "=a" (a), "=d" (d)
:
:);
return ((ticks)a) | (((ticks)d) << 32);
}
-O3的优化,但return value一定要存下来参与difference的计算.
我在一台xeon sandy bridge上的结果可以稳定在32个clock.偶尔有36个clock
objdump后的可以看到基本就是下面这段代码的重复(intel style)
rdtscp
shl rdx. 0x20
mov eax,eax
or rdx,rax
mov QWORD PTR[rsp+0x228],rdx
5条instruction也就是32个clock的差别,其中还包括一个mov 到memory
的操作.
+++++++++++
你不按照 Intel 建议的方式就没有什么信服力。
而且我的反例也有了。

【在 S*A 的大作中提到】
: 所以我很迷惑,你似乎知道很多内部细节,但是你又忽律
: 很多重要的技术细节。你不按照 Intel 建议的方式来测量,
: 然后抱怨有意想不到的结果。
: 你现在还是没有论据支持你的1000 cycle 的说法。我对 Intel
: CPU 还算比较了解也不敢按照你那样乱推测。我感觉你的
: 测量就没有可靠性。
: 就算我退一步,按照你的思路,50个pipeline,先假设
: Intel CPU 里面就是这样工作的。你的论据也不成立。
: rdtsc 单单一个 instruction 就有 250-300 cycle。
: 你只要pipelien 里面有 4 个 rdtsc 那样的 instruction,

avatar
x*l
74
能把你修改后的getticks()贴一下吗?

【在 S*A 的大作中提到】
: 请问你去编译运行了 LZ 的程序了吗?
: 你知道他的嵌入汇编有什么错误吗? 包括 rdtscp 的版本,
: 现在还有。这个测量结果就不是那么信服。
: 又退一步来说,如果你认为 nmi 什么的可以忽律,
: 那同样道理 scheduling method 就可忽律。
: 那么我的更正的程序的结果就有说服力了。
: 我的程序修正了读 TSC 的 bug, 测量出没有这种差别。
: 至少差别是在 variance 里面的。

avatar
z*n
75
根本问题是 中断没有关,在任何情况下都可能会被切换出去做别的事情,
很难理解吗

【在 x**l 的大作中提到】
: 能把你修改后的getticks()贴一下吗?
avatar
z*n
76
一知半解君发intel手册不看的,最大绝对误差176
如果你的两种情况的值是稳定的,因为有误差,所一绝对意义不大
可是当比较的时候,比较意义大,因为都带着误差

【在 x**l 的大作中提到】
: 能把你修改后的getticks()贴一下吗?
avatar
z*n
77
根本问题是中断,这个帖子里有人说driver也在说中断,
你就抓些没有的

【在 S*A 的大作中提到】
: 是吗,你是刚学 system call 和 spinlock 一定什么
: 东西都要扯上吗?
: 我只是觉得这个 1000 cycle 的差别和 system call
: 和 spinlock 关系不大。
: 请你这个 CS 专业的来示范一下如何用 system call
: 和 spinlock 解释这个 1000 cycle 的差别,让我们
: 看看是不是很牵强。

avatar
S*A
78
我就简短点说吧,
你的 rdtsc 第一个版本先是有后面的 cpuid 冲掉了前面的 rdtsc 的
EAX EDX 寄存器,
修改改后的第二个版本应该先做 CPUID 然后做 RDTSC。看
Intel 手册。
你的 rdtscp 的汇编版本放开 out of order 不说,rdtscp 会
clobber ECX 寄存器,在里面存 CPU ID。你的汇编没有告诉
gcc 你破坏了 ECX 寄存器。虽然你用了 volatile, 那个只是
告诉 gcc 你有其他的 memory side effect (其实你没有)。
你仍然需要告诉 gcc clobber ECX。
然后正确的读 RDTSC 和 RDTSCP 的嵌入汇编代码在 24 楼
的 Intel pdf 里面都有,我就不重复了。
我没有用虚拟机。
你那个 1000 cycle 的差别不可能是中间被 schedule 其他的
thread。 单单 schedule 一次 task 就要 1000 cycle 这个数
量极。你要换出去换回来是不可能的。而且也不能解释这个
刚刚好每个 work() 都被抢先 schedule 掉。我不理解你
为什么要在 user space 玩这些 schedule 的 game。 如果
你要比较确定的控制 CPU 行为,你应该用 kernel module,
例如 Intel pdf 里面做的那样,你就可以整个 disable preempt。
我还是不能信服你的测量结果,因为你没有排除 out of order。
如果你能够收集一个排除 out of order 的结果,多做几次这个
会比较有意义。大家在这里瞎猜 out of order 到底有多少影响
是在浪费时间。
我想到一个假设的理论可能解释这个现象。你在 GAP()里面
花比较长时间的循环以后,CPU expire 了 work() 那些代码的
instruction cache。导致进入 work()的时候需要从新 decode
instruction, 然后就多了一些时间。或者你很长时间没有访问
data memory,导致其中一些 work() 用到的 data cache
被 expired 了。或者是 work() 循环里的 branch predict
被仍掉了。你想想,如果是 1 秒钟以后才用到,这样的
频率也太低了,被仍掉是完全有可能的。至于 Intel 的 cache
expire 用什么具体的算法就是完全超出我知道的范围了。
所以这些也只能推测。
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。