我正在使用以下方法在紧密循环(比如5000次迭代)中测试函数的性能timer:tc/3
:
{Duration_us, _Result} = timer:tc(M, F, [A])
Run Code Online (Sandbox Code Playgroud)
这将返回持续时间(以微秒为单位)和函数的结果.为了论证,持续时间是N微秒.
然后,我对迭代结果执行简单的平均计算.
如果我把一个timer:sleep(1)
函数调用之前的timer:tc/3
呼吁,为所有迭代的平均时间总是>没有睡眠的平均数:
timer:sleep(1),
timer:tc(M, F, [A]).
Run Code Online (Sandbox Code Playgroud)
这对我来说没有多大意义,因为timer:tc/3
函数应该是原子的,而不关心它之前发生的任何事情.
谁能解释这个奇怪的功能?它是否与调度和减少有关?
你的意思是这样的:
4> 富:富(10000)。
在哪里:
-module(foo).
-export([foo/1, baz/1]).
foo(N) -> TL = bar(N), {TL,sum(TL)/N} .
bar(0) -> [];
bar(N) ->
timer:sleep(1),
{D,_} = timer:tc(?MODULE, baz, [1000]),
[D|bar(N-1)]
.
baz(0) -> ok;
baz(N) -> baz(N-1).
sum([]) -> 0;
sum([H|T]) -> H + sum(T).
Run Code Online (Sandbox Code Playgroud)
我尝试过这个,很有趣。使用 sleep 语句,timer:tc/3 返回的平均时间为 19 到 22 微秒,如果注释掉 sleep,平均值会下降到 4 到 6 微秒。相当戏剧化!
我注意到计时中存在人为因素,因此像这样的事件(这些数字是计时器返回的单个微秒计时:tc/3)并不罕见:
---- snip ----
5,5,5,6,5,5,5,6,5,5,5,6,5,5,5,5,4,5,5,5,5,5,4,5,5,5,5,6,5,5,
5,6,5,5,5,5,5,6,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,4,5,
5,5,5,6,5,5,5,6,5,5,7,8,7,8,5,6,5,5,5,6,5,5,5,5,4,5,5,5,5,
14,4,5,5,4,5,5,4,5,4,5,5,5,4,5,5,4,5,5,4,5,4,5,5,5,4,5,5,4,
5,5,4,5,4,5,5,4,4,5,5,4,5,5,4,4,4,4,4,5,4,5,5,4,5,5,5,4,5,5,
4,5,5,4,5,4,5,5,5,4,5,5,4,5,5,4,5,4,5,4,5,4,5,5,4,4,4,4,5,4,
5,5,54,22,26,21,22,22,24,24,32,31,36,31,33,27,25,21,22,21,
24,21,22,22,24,21,22,21,24,21,22,22,24,21,22,21,24,21,22,21,
23,27,22,21,24,21,22,21,24,22,22,21,23,22,22,21,24,22,22,21,
24,21,22,22,24,22,22,21,24,22,22,22,24,22,22,22,24,22,22,22,
24,22,22,22,24,22,22,21,24,22,22,21,24,21,22,22,24,22,22,21,
24,21,23,21,24,22,23,21,24,21,22,22,24,21,22,22,24,21,22,22,
24,22,23,21,24,21,23,21,23,21,21,21,23,21,25,22,24,21,22,21,
24,21,22,21,24,22,21,24,22,22,21,24,22,23,21,23,21,22,21,23,
21,22,21,23,21,23,21,24,22,22,22,24,22,22,41,36,30,33,30,35,
21,23,21,25,21,23,21,24,22,22,21,23,21,22,21,24,22,22,22,24,
22,22,21,24,22,22,22,24,22,22,21,24,22,22,21,24,22,22,21,24,
22,22,21,24,21,22,22,27,22,23,21,23,21,21,21,23,21,21,21,24,
21,22,21,24,21,22,22,24,22,22,22,24,21,22,22,24,21,22,21,24,
21,23,21,23,21,22,21,23,21,23,22,24,22,22,21,24,21,22,22,24,
21,23,21,24,21,22,22,24,21,22,22,24,21,22,21,24,21,22,22,24,
22,22,22,24,22,22,21,24,22,21,21,24,21,22,22,24,21,22,22,24,
24,23,21,24,21,22,24,21,22,21,23,21,22,21,24,21,22,21,32,31,
32,21,25,21,22,22,24,46,5,5,5,5,5,4,5,5,5,5,6,5,5,5,5,5,5,4,
6,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,4,5,4,5,5,5,5,6,5,5,5,5,5,
5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,4,6,4,6,5,5,5,5,5,5,4,6,5,5,5,
5,4,5,5,5,5,5,5,6,5,5,5,5,4,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,
5,5,5,4,5,5,6,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,
6,5,5,5,5,4,5,4,5,5,5,5,6,5,5,5,5,5,5,4,5,4,5,5,5,5,5,6,5,5,
5,5,4,5,4,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,
---- snip ----
Run Code Online (Sandbox Code Playgroud)
我认为这就是您所指的效果,尽管当您说“ always > N”时,是“ always ”还是“大部分”?无论如何,并不总是适合我。
上述结果摘录是在没有睡眠的情况下进行的。通常,当使用睡眠计时器时:tc/3 在没有睡眠的情况下,大多数时间会返回 4 或 5 等低时间,但有时会返回 22 等大时间,并且在睡眠到位后,通常会返回 22 等大时间,偶尔会出现一批低时间。
为什么会发生这种情况当然并不明显,因为睡眠实际上只是意味着产出。我想知道这一切是否与CPU缓存有关。毕竟,特别是在一台不忙的机器上,人们可能会期望没有睡眠的情况能够一次性执行大部分代码,而无需将其移动到另一个核心,而不需要对核心做太多其他事情,从而充分利用从缓存中...但是当您睡眠并因此屈服并稍后返回时,缓存命中的机会可能会大大减少。
归档时间: |
|
查看次数: |
859 次 |
最近记录: |