Re:多线程。 [英] Re: multithreading.

查看:68
本文介绍了Re:多线程。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Jon Harrop< us **** @ jdh30.plus.comwrites:

Jon Harrop <us****@jdh30.plus.comwrites:


让我们先做一个单线程基准测试。
Let''s do a single-threaded benchmark first.

>什么是集合密集型任务?
>What collection-intensive tasks?



符号重写将成为一个很好的基准。这是一个:

http:// www。 lambdassociates.org/studies/study10.htm


尝试使用引用计数实现这一点,我们可以看到它是如何比较b / b
棘手的重写)。用双精度替换任意精度

整数。


Symbolic rewriting would make a good benchmark. Here is one:

http://www.lambdassociates.org/studies/study10.htm

Try implementing this using reference counting and we can see how it
compares (probably on a trickier rewrite). Replace the arbitrary-precision
ints with doubles.



我读过新闻的(旧)机器并不像Mark'

那么强大,所以在这里参考'稍微修改版本的时间[1]

O''Caml代码: -


$ ocamlopt -v

Objective Caml本机代码编译器,版本3.08.2

标准库目录:/usr/lib/ocaml/3.08

$ ocamlopt simplify.ml -o simplified

$时间./简化

获得5.020000s


真实0m5.137s

用户0m5。 021s

sys 0m0.005s


现在使用天真引用计数的C代码: -


$ cc -v

从/usr/lib/gcc-lib/i486-linux/3.3.5/specs阅读规格

配置:../ src / configure -v --enable-languages = c,c ++,java,f77,pascal,objc,ada,treelang --prefix = / usr --mandir = / usr / share / man --infodir = / usr / share / info --with -gxx-include-dir = / usr / include / c ++ / 3.3 --enable-shared --with-system-zlib --enable-nls --wi thout-included-gettext --enable -__ cxa_atexit --enable-clocale = gnu --enable-debug --enable-java-gc = boehm --enable-java-awt = xlib --enable-objc-gc i486-linux

线程模型:posix

gcc版本3.3.5(Debian 1:3.3.5-8ubuntu2.1)

$ cc -O3 - Wall simplify.c -o简化

$ time ./simplify

real 0m16.757s

用户0m16.553s

sys 0m0.003s

$


这比O''Caml慢3倍以上,所以O''Caml / GC是赢家,对吗?


如果您唯一的选择是O''Caml或(天真)引用计数

这个问题那么肯定。但是,还有其他方法。对于

的例子,以下是C代码的时间,它使用手动编码的b $ b版本实现的足够智能的编译器

线性/独特类型可以产生: -


$ time ./simplify

real 0m2.812s

用户0m2.751s

sys 0m0.002s


所以在我的机器上天真的引用计数比O''Caml GC慢3倍

但线性版本比O''Caml快2倍。我们应该得出结论(O''Caml)GC和天真的引用计数都很糟糕吗?


我的结论是,虽然基准测试明确地衡量某些东西/>
我不清楚它测量的是有趣/有用的。它可以使b b b变得有用,在这种情况下,基准测试应该跟踪峰值/平均堆大小。目前,这是毫无意义的b $ b因为测试表达式太小,每次迭代的工作集只需要几百个字节。这将适用于任何世代收藏家的托儿所,或者仅需要复制

收藏家来遍历几百个字节。那是非常友好的GC。


------------------


[1]从网站编译代码给出了以下内容: -


$ ocamlopt simplify.ml -o简化

没有为以下模块提供实现:

num是从simplify.cmx引用


如果我使用的是过时的话,而不是锻炼

O''Caml或它只是没有正确安装,我只是将代码更改为

使用一个好的旧数据类型,并且工作正常: -


$ cat simplify.ml

type expr = int of int |变量字符串|添加expr * expr | Mul的expr * expr ;;


let int n =(Int n);;


let(+:)fg = Add( f,g)和(*:)fg = Mul(f,g);;


let test_expr =

Var" x" * :((int 12 *:int 0 + :( int 23 +:int 8))+:Var" y");;


让时间fx =

让t = Sys.time()in

让f_x = fx in

Printf.printf" Took%fs \ n" (Sys.time() - 。t);

f_x ;;


让rec loop nfx =如果n = 1则fx else(忽略(fx) ); loop(n-1)fx);;


让rec(+:)fg =匹配f,g与

| Int n,Int m -Int(n + m)

| (Int 0),e | e,(Int 0)-e

| f,加(g,h)-f +:g +:h

| f,g -Add(f,g);;


让rec(*:)f g =匹配f,g与

| Int n,Int m -Int(n * m)

| (Int 0),e | e,(Int 0) - (Int 0)

| (Int 1),e | e,(Int 1)-e

| f,Mul(g,h)-f *:g *:h

| f,g -Mul(f,g);;


让rec简化=功能

| Int _ | Var _ as f -f

|添加(f,g) - 简化f +:简化g

| Mul(f,g) - 简化f *:简化g ;;


时间(循环10000000简化)test_expr ;;

The (old) machine I read news on is not nearly so powerful as Mark''s
so for reference here''s the time for a slightly modified version[1] of
the O''Caml code :-

$ ocamlopt -v
The Objective Caml native-code compiler, version 3.08.2
Standard library directory: /usr/lib/ocaml/3.08
$ ocamlopt simplify.ml -o simplify
$ time ./simplify
Took 5.020000s

real 0m5.137s
user 0m5.021s
sys 0m0.005s

Now for C code that uses naive reference counting :-

$ cc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.5/specs
Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux
Thread model: posix
gcc version 3.3.5 (Debian 1:3.3.5-8ubuntu2.1)
$ cc -O3 -Wall simplify.c -o simplify
$ time ./simplify
real 0m16.757s
user 0m16.553s
sys 0m0.003s
$

That''s over 3x slower than O''Caml so O''Caml/GC is the winner, right?

We''ll if your only choice is O''Caml or (naive) reference counting for
this problem then yes. However, there are other approaches. For
example, the following is the time for C code that uses a hand-coded
version of what a sufficiently smart compiler that implemented
linear/unique types could produce :-

$ time ./simplify
real 0m2.812s
user 0m2.751s
sys 0m0.002s

So on my machine naive reference counting is 3x slower than O''Caml GC
but the linear version is 2x faster than O''Caml. Should we conclude
that (O''Caml) GC and naive reference counting both suck?

My conclusion is that while the benchmark clearly measures something
it isn''t clear to me that what it measures is interesting/useful. It
may be possible to make it useful in which case the benchmark should
also track peak/average heap size. At present that''s pointless
because the the test expression is so small that the working set for
each iteration should only be a few hundred bytes. This will fit in
the nursery of any generational collector or only require a copying
collector to traverse a few hundred bytes. That''s very GC friendly.

------------------

[1] Compiling the code from the site gave the following :-

$ ocamlopt simplify.ml -o simplify
No implementations provided for the following modules:
Num referenced from simplify.cmx

Rather than work out if I''m suffering from using an out of date
O''Caml or it just isn''t installed right, I just changed the code to
use a good old data type and that works fine :-

$ cat simplify.ml
type expr = Int of int | Var of string | Add of expr * expr | Mul of expr * expr;;

let int n = (Int n);;

let ( +: ) f g = Add(f, g) and ( *: ) f g = Mul(f, g);;

let test_expr =
Var "x" *: ((int 12 *: int 0 +: (int 23 +: int 8)) +: Var "y");;

let time f x =
let t = Sys.time() in
let f_x = f x in
Printf.printf "Took %fs\n" (Sys.time() -. t);
f_x;;

let rec loop n f x = if n=1 then f x else (ignore(f x); loop (n-1) f x);;

let rec ( +: ) f g = match f, g with
| Int n, Int m -Int (n + m)
| (Int 0), e | e, (Int 0) -e
| f, Add(g, h) -f +: g +: h
| f, g -Add(f, g);;

let rec ( *: ) f g = match f, g with
| Int n, Int m -Int (n * m)
| (Int 0), e | e, (Int 0) -(Int 0)
| (Int 1), e | e, (Int 1) -e
| f, Mul(g, h) -f *: g *: h
| f, g -Mul(f, g);;

let rec simplify = function
| Int _ | Var _ as f -f
| Add (f, g) -simplify f +: simplify g
| Mul (f, g) -simplify f *: simplify g;;

time (loop 10000000 simplify) test_expr;;

推荐答案

ocamlopt -v

Objective Caml本机代码编译器,版本3.08.2

标准库目录:/usr/lib/ocaml/3.08
ocamlopt -v
The Objective Caml native-code compiler, version 3.08.2
Standard library directory: /usr/lib/ocaml/3.08


ocamlopt simplify.ml -o简化
ocamlopt simplify.ml -o simplify


time ./simplify

Took 5.020000s


真实0m5.137s

用户0m5.021s

sys 0m0.005s


现在使用天真引用计数的C代码: -

time ./simplify
Took 5.020000s

real 0m5.137s
user 0m5.021s
sys 0m0.005s

Now for C code that uses naive reference counting :-


这篇关于Re:多线程。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆