Erlang 测量进程执行时间和reduction
2016-12-14 03:50
281 查看
Erlang的进程调度不是使用时间片的分配, 而是给每个进程或Port分配一个reduction budget, 默认值是2000. 每个操作都会花费reduction, 一旦reduction budget用完,该进程就会释放CPU,然后被重新调度,再次分配到CPU的时候又分配了2000 reduction budget, 循环往复.
#问题一, 如何测量一个进程消费了多少reduction呢 ?
答案是使用函数process_info(Pid, reductions), 下面用一个例子用来说明如何获取一个进程花费的reduction.
11> Pid = spawn(fun()->receive First->first end, receive Second->second end, receive Over->ok end end). %%创建一个进程,该进程接收三次消息后结束.
<0.73.0>
12> process_info(Pid, reductions).
{reductions,17} %%到receive First位置挂起, 一共花费17 个reduction
13> process_info(Pid, reductions).
{reductions,17} %%此时进程被挂起, reduction 不会发生变化
14>
14>
14> Pid!first.
first
15> process_info(Pid, reductions).
{reductions,38} %%到receive Second位置挂起, 一共花费38 个reduction
16> process_info(Pid, reductions).
{reductions,38} %%此时进程被挂起, reduction 不会发生变化
17>
17>
17> Pid!second.
second
18> process_info(Pid, reductions).
{reductions,69} %%到receive Over位置挂起, 一共花费69 个reduction
19> process_info(Pid, reductions).
{reductions,69} %%此时进程被挂起, reduction 不会发生变化
20>
20> Pid!over.
#问题二, 如何测量一个进程运行了多长时间呢 ?
答案是使用函数timer:tc, 下面用一个例子用来说明如何获取一个进程花费的时间.
#test_tc.erl
-module(test_tc).
-compile(export_all).
start(N)->tail_fac(N).
tail_fac(N) -> tail_fac(N,1).
tail_fac(0,Acc) -> Acc;
tail_fac(N,Acc) when N > 0 -> tail_fac(N-1,N+Acc).
11> timer:tc(test_tc, start, [1]).
{2,2} %%执行start(1)花费了2微秒, 单位是百万分之一秒
12> timer:tc(test_tc, start, [10]).
{2,56} %%执行start(10)花费了2微秒, 单位是百万分之一秒
13> timer:tc(test_tc, start, [100]).
{5,5051} %%执行start(100)花费了5微秒, 单位是百万分之一秒
14> timer:tc(test_tc, start, [1000]).
{34,500501} %%执行start(1000)花费了34微秒, 单位是百万分之一秒
15> timer:tc(test_tc, start, [10000]).
{351,50005001} %%执行start(10000)花费了351微秒, 单位是百万分之一秒
16> timer:tc(test_tc, start, [100000]).
{3790,5000050001}
17> timer:tc(test_tc, start, [1000000]).
{31207,500000500001}
18> timer:tc(test_tc, start, [10000000]).
{341392,50000005000001}
19> timer:tc(test_tc, start, [100000000]).
{2227879,5000000050000001} %执行start(100000000)花费了大约2秒
#问题三, 如何测量一个reduction是多长时间呢 ?
答案是把以上两种测量关联起来,即可计算出一个reduction大约是多少时间,具体时间应该和测试环境是有依赖关系的.
下面用一个例子用来说明,同样使用上面的测试文件test_tc.erl
23> Pid = spawn(fun()->receive Number->test_tc:start(Number) end, receive Over->ok end end). %%收到消息(计算的数字), 开始执行start函数
<0.82.0>
24>
24> process_info(Pid, reductions).
{reductions,17} %%到receive Number位置挂起, 一共花费69 个reduction
25> process_info(Pid, reductions).
{reductions,17}
26> Pid!10. %%发送数字10到Pid, 触发start函数
27> process_info(Pid, reductions).
{reductions,87} %%到receive Over位置挂起, start函数一共花费87-17 个reduction
28> process_info(Pid, reductions).
{reductions,87}
29> f().
ok
30> Pid = spawn(fun()->receive Number->test_tc:start(Number) end, receive Over->ok end end).
<0.90.0>
31> process_info(Pid, reductions).
{reductions,17}
32> process_info(Pid, reductions).
{reductions,17}
33> Pid!1000. %%发送数字1000到Pid, 触发start函数
34> process_info(Pid, reductions).
{reductions,1077} %%到receive Over位置挂起, start函数一共花费1077-17 个reduction
35> process_info(Pid, reductions).
{reductions,1077}
结合问题二里面的数据,我们可以计算出 start(1000) 花费了1060个reduction, 34微秒. 1000 reduction 大约等于34 微秒, 不同的测试环境, 数字肯定会有不同.
#测试环境》
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 2400.000
BogoMIPS: 4800.00
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
NUMA node0 CPU(s): 0-7
##博客仅作个人记录##
#问题一, 如何测量一个进程消费了多少reduction呢 ?
答案是使用函数process_info(Pid, reductions), 下面用一个例子用来说明如何获取一个进程花费的reduction.
11> Pid = spawn(fun()->receive First->first end, receive Second->second end, receive Over->ok end end). %%创建一个进程,该进程接收三次消息后结束.
<0.73.0>
12> process_info(Pid, reductions).
{reductions,17} %%到receive First位置挂起, 一共花费17 个reduction
13> process_info(Pid, reductions).
{reductions,17} %%此时进程被挂起, reduction 不会发生变化
14>
14>
14> Pid!first.
first
15> process_info(Pid, reductions).
{reductions,38} %%到receive Second位置挂起, 一共花费38 个reduction
16> process_info(Pid, reductions).
{reductions,38} %%此时进程被挂起, reduction 不会发生变化
17>
17>
17> Pid!second.
second
18> process_info(Pid, reductions).
{reductions,69} %%到receive Over位置挂起, 一共花费69 个reduction
19> process_info(Pid, reductions).
{reductions,69} %%此时进程被挂起, reduction 不会发生变化
20>
20> Pid!over.
#问题二, 如何测量一个进程运行了多长时间呢 ?
答案是使用函数timer:tc, 下面用一个例子用来说明如何获取一个进程花费的时间.
#test_tc.erl
-module(test_tc).
-compile(export_all).
start(N)->tail_fac(N).
tail_fac(N) -> tail_fac(N,1).
tail_fac(0,Acc) -> Acc;
tail_fac(N,Acc) when N > 0 -> tail_fac(N-1,N+Acc).
11> timer:tc(test_tc, start, [1]).
{2,2} %%执行start(1)花费了2微秒, 单位是百万分之一秒
12> timer:tc(test_tc, start, [10]).
{2,56} %%执行start(10)花费了2微秒, 单位是百万分之一秒
13> timer:tc(test_tc, start, [100]).
{5,5051} %%执行start(100)花费了5微秒, 单位是百万分之一秒
14> timer:tc(test_tc, start, [1000]).
{34,500501} %%执行start(1000)花费了34微秒, 单位是百万分之一秒
15> timer:tc(test_tc, start, [10000]).
{351,50005001} %%执行start(10000)花费了351微秒, 单位是百万分之一秒
16> timer:tc(test_tc, start, [100000]).
{3790,5000050001}
17> timer:tc(test_tc, start, [1000000]).
{31207,500000500001}
18> timer:tc(test_tc, start, [10000000]).
{341392,50000005000001}
19> timer:tc(test_tc, start, [100000000]).
{2227879,5000000050000001} %执行start(100000000)花费了大约2秒
#问题三, 如何测量一个reduction是多长时间呢 ?
答案是把以上两种测量关联起来,即可计算出一个reduction大约是多少时间,具体时间应该和测试环境是有依赖关系的.
下面用一个例子用来说明,同样使用上面的测试文件test_tc.erl
23> Pid = spawn(fun()->receive Number->test_tc:start(Number) end, receive Over->ok end end). %%收到消息(计算的数字), 开始执行start函数
<0.82.0>
24>
24> process_info(Pid, reductions).
{reductions,17} %%到receive Number位置挂起, 一共花费69 个reduction
25> process_info(Pid, reductions).
{reductions,17}
26> Pid!10. %%发送数字10到Pid, 触发start函数
27> process_info(Pid, reductions).
{reductions,87} %%到receive Over位置挂起, start函数一共花费87-17 个reduction
28> process_info(Pid, reductions).
{reductions,87}
29> f().
ok
30> Pid = spawn(fun()->receive Number->test_tc:start(Number) end, receive Over->ok end end).
<0.90.0>
31> process_info(Pid, reductions).
{reductions,17}
32> process_info(Pid, reductions).
{reductions,17}
33> Pid!1000. %%发送数字1000到Pid, 触发start函数
34> process_info(Pid, reductions).
{reductions,1077} %%到receive Over位置挂起, start函数一共花费1077-17 个reduction
35> process_info(Pid, reductions).
{reductions,1077}
结合问题二里面的数据,我们可以计算出 start(1000) 花费了1060个reduction, 34微秒. 1000 reduction 大约等于34 微秒, 不同的测试环境, 数字肯定会有不同.
#测试环境》
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 2400.000
BogoMIPS: 4800.00
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
NUMA node0 CPU(s): 0-7
##博客仅作个人记录##
相关文章推荐
- 【程序语言】C++中的执行时间测量
- 测量程序执行需要的时间
- MFC下测量程序执行时间
- Java精确测量代码运行时间 代码执行时间 纳秒 nanoTime
- Java精确测量代码运行时间 代码执行时间 纳秒 nanoTime
- 测量程序执行时间的两种方法
- Java、Android超精确测量代码执行时间差
- 测量某断代码执行时间-代码
- 测量某断代码执行时间-代码
- [Linux小技巧]如何查询进程执行时间
- c#关闭系统进程以及如何调用cmd并执行命令开发者在线 Builder.com.cn 更新时间:2008-08-05作者:乔毅 来源:IT168
- oracle 中--怎么查看当前表空间在作什么操作?--查锁,死锁,当前执行时间长的Sql语句,没提交的事务,对象为哪些进程所用
- 18、深入理解计算机系统笔记:测量程序执行时间
- VC 6.0 代码执行时间测量 代码
- 程序执行时间测量
- 测量java代码的执行时间
- oracle 中--怎么查看当前表空间在作什么操作?--查锁,死锁,当前执行时间长的Sql语句,没提交的事务,对象为哪些进程所用
- 执行时间测量
- 【C语言】程序执行时间测量
- 根据进程查找该进行的执行位置和完整执行指令和检查文件开始生成时间