由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 请教:属于google不到答案的问题
相关主题
两个古董的C优化代码,现在还有效果么?Clock() problem
C++在linux下读一次系统时间要多少时间C++ 问题紧急求救
线程中可以循环延时吗?问一个C\C++中clock()函数溢出问题
C++的牛B之处你们都还没体会到C 程序 clock() timer 问题
请不要盲目崇拜FP语言DHCP server
CIH源代码请问有人用过photran么
科普贴,fusion IO怎样高效管理内存?
怎样中断一个正在等待的Java线程比较好?(ZT) 怎样学习RTOS?
相关话题的讨论汇总
话题: cycles话题: clock话题: dummy话题: working话题: gap
进入Programming版参与讨论
1 (共1页)
x**l
发帖数: 64
1
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****u
发帖数: 44466
2
这是操作系统原理的基本问题。。。

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

x**l
发帖数: 64
3
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] 改变调度策略,然后按任意键继续.
谢谢大家了.
x**l
发帖数: 64
4
谢谢,没错,大方向容易理解,现在缺少的是具体的细节原因.

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

x****u
发帖数: 44466
5
你这个有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

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

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

x****u
发帖数: 44466
7
那把这段代码直接改为驱动不就完事了?

kernel

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

x**l
发帖数: 64
8
为什么改成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

x****u
发帖数: 44466
9
用户态下你可以控制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.

x**l
发帖数: 64
10
请问比user space 下的policy 级别高的有哪些? 能给个link吗?

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

相关主题
CIH源代码Clock() problem
科普贴,fusion IOC++ 问题紧急求救
怎样中断一个正在等待的Java线程比较好?问一个C\C++中clock()函数溢出问题
进入Programming版参与讨论
x****u
发帖数: 44466
11
比如抢占啊,中断啊。
就算你设了CPU亲和度也不是绝对的。

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

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

x****u
发帖数: 44466
13
你用的命令做不到啊。

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

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

【在 x****u 的大作中提到】
: 你用的命令做不到啊。
x****u
发帖数: 44466
15
这些东西不是为了实时系统设计的,你不应该在普通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都会受完全
: 一致的影响.

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

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

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

x****k
发帖数: 2932
18
没有任务切换,100%CPU独占,无浮点,无sys call,only one thread on the core.
interrupt shield,

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

core.

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

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

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

相关主题
C 程序 clock() timer 问题怎样高效管理内存?
DHCP server(ZT) 怎样学习RTOS?
请问有人用过photran么btw, MS C++ 是ECMA-372标准
进入Programming版参与讨论
x****u
发帖数: 44466
21
俗称跑飞了

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

x****k
发帖数: 2932
22
我的情况不属于跑飞了

【在 x****u 的大作中提到】
: 俗称跑飞了
S*A
发帖数: 7142
23
这个不属于跑飞了,跑飞了是指 PC (EIP) 指到代码段以外的地方去了。
你的程序我的 core 2 due 跑不了, illegal instruction。 应该就是
那个 rdtscp 的汇编指令。rdtscp 是 i7 才引入的。
S*A
发帖数: 7142
24
我想我知道你描述的问题了。
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
x****u
发帖数: 44466
25
楼主说
“我知道在某些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

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

杂程

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

x**l
发帖数: 64
27
谢谢回复
测量方式是存在误差,绝对不会产生大于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 完全有可能使结果看上去更接近。
:
: 杂程

G********f
发帖数: 17
28
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

x**l
发帖数: 64
29
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

G********f
发帖数: 17
30
what about L2 ?

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

相关主题
请教如何用程序判断当前声卡是否有声音放出来C++在linux下读一次系统时间要多少时间
为啥大家都比较python的web framework呢线程中可以循环延时吗?
两个古董的C优化代码,现在还有效果么?C++的牛B之处你们都还没体会到
进入Programming版参与讨论
x**l
发帖数: 64
31
我专门把code和data size限制小于L1 size. 32K byte

【在 G********f 的大作中提到】
: what about L2 ?
S*A
发帖数: 7142
32

你自己跑过你这样的测量程序吗,肯定没有吧。我随便看一眼你这段修改过
嵌入汇编就有至少2处影响结果的错误。要不你先改好了先测一下吧。
这个就留给你做功课了。
关于 out of order, 你知道 Intel 内部是翻译成完全不同的 micro code
执行的吧?连 register 都是 remap 过的。 所以你说绝对不会产生 1000
clocks 级别的误差从那里来的,有 Intel 官方的出处吗?
我只是很奇怪你为什么不先修正了你的程序再讨论。
[ssa]$ sudo ./a.out 1 0
allocate mem@0xbb6010
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 mem@0xfdb010
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 mem@0x2475010
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 mem@0x1a8a010
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));

z*******n
发帖数: 1034
33
手机操作系统现在至少是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

S*A
发帖数: 7142
34
这个程序有汇编,手机那个 rdtsp 的指令是跑不了的。

讨论

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

z*******n
发帖数: 1034
35
基本概念 代码无关

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

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

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

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

x**l
发帖数: 64
38
谢谢你指出错误,匆忙之中修改的,没有测试.
如果你的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 mem@0x606010
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 mem@0x606010
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 mem@0x606010
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 mem@0x606010
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 平台上的。
: 而且这个问题很可能本来就不是个问题。

x**l
发帖数: 64
39
关于不超过1000 clock误差,主要是基于对架构的理解。
x86的instruction是非等长的cisc指令,在内部会翻译成等长指令执行。但不管怎样变
,内部始终是基于pipeline的,在没有pipeline stallment情况下,pipeline入口和出
口肯定是按序的,所以无论后面的instruction跳到前面执行,也限制在pipeline的长
度内。
我记得网上有review关于intel的sandy bridge,提到了pipeline的级数,不会超过50。
回到我的代码,就算rdtscp被后面的instruction 插了,在这个简单循环中,最后的
clock数是靠将两次rdtscp的结果相减获得的,所以误差会相互抵消.
k**********g
发帖数: 989
40
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.
相关主题
C++的牛B之处你们都还没体会到科普贴,fusion IO
请不要盲目崇拜FP语言怎样中断一个正在等待的Java线程比较好?
CIH源代码Clock() problem
进入Programming版参与讨论
S*A
发帖数: 7142
41
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)
: :

S*A
发帖数: 7142
42
所以我很迷惑,你似乎知道很多内部细节,但是你又忽律
很多重要的技术细节。你不按照 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的结果相减获得的,所以误差会相互抵消.

z*******n
发帖数: 1034
43
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, 如何

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

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

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

S*A
发帖数: 7142
46
这个文档我在 24 楼贴过啦, LZ 应该好好读一下。

【在 z*******n 的大作中提到】
: 你不是爱读intel的文档吗
: 这有一个
: http://www.intel.com/content/dam/www/public/us/en/documents/whi

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

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

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

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

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

相关主题
C++ 问题紧急求救DHCP server
问一个C\C++中clock()函数溢出问题请问有人用过photran么
C 程序 clock() timer 问题怎样高效管理内存?
进入Programming版参与讨论
S*A
发帖数: 7142
51
不明白你问这个和原来的问题有什么关系。
楼太歪了。

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

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

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

【在 z*******n 的大作中提到】
: 你基础知识太差 是cs专业的么
x**l
发帖数: 64
54

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, 如何

x**l
发帖数: 64
55

所以我很迷惑,你似乎知道很多内部细节,但是你又忽律
很多重要的技术细节。你不按照 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,

x**l
发帖数: 64
56
能把你修改后的getticks()贴一下吗?

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

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

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

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

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

S*A
发帖数: 7142
60
我就简短点说吧,
你的 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 用什么具体的算法就是完全超出我知道的范围了。
所以这些也只能推测。
1 (共1页)
进入Programming版参与讨论
相关主题
(ZT) 怎样学习RTOS?请不要盲目崇拜FP语言
btw, MS C++ 是ECMA-372标准CIH源代码
请教如何用程序判断当前声卡是否有声音放出来科普贴,fusion IO
为啥大家都比较python的web framework呢怎样中断一个正在等待的Java线程比较好?
两个古董的C优化代码,现在还有效果么?Clock() problem
C++在linux下读一次系统时间要多少时间C++ 问题紧急求救
线程中可以循环延时吗?问一个C\C++中clock()函数溢出问题
C++的牛B之处你们都还没体会到C 程序 clock() timer 问题
相关话题的讨论汇总
话题: cycles话题: clock话题: dummy话题: working话题: gap