Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何使用GNU并行编写多核排序_Multithreading_Bash_Sorting_Parallel Processing_Gnu Parallel - Fatal编程技术网

Multithreading 如何使用GNU并行编写多核排序

Multithreading 如何使用GNU并行编写多核排序,multithreading,bash,sorting,parallel-processing,gnu-parallel,Multithreading,Bash,Sorting,Parallel Processing,Gnu Parallel,GNU parallel是一个shell工具,用于使用一台或多台计算机并行执行作业 例如,如果我想编写多核版本的wc,我可以: cat XXX | parallel --block 10M --pipe wc -l | awk 'BEGIN{count=0;}{count = count+ $1;} END{print count;}' 我的问题是如何使用并行进行排序?我知道我应该做的是将并行结果通过管道传输到“合并排序文件”命令(就像合并排序中的最终合并),但我不知道如何做到这一点。有几种方

GNU parallel是一个shell工具,用于使用一台或多台计算机并行执行作业

例如,如果我想编写多核版本的
wc
,我可以:

cat XXX | parallel --block 10M --pipe wc -l | awk 'BEGIN{count=0;}{count = count+ $1;} END{print count;}'

我的问题是如何使用并行进行排序?我知道我应该做的是将并行结果通过管道传输到“合并排序文件”命令(就像合并排序中的最终合并),但我不知道如何做到这一点。

有几种方法可以做到这一点

让我们使用一个简单的文本文件:

$ curl http://www.gutenberg.org/cache/epub/2701/pg2701.txt 2>/dev/null |
   tr " " "\n" | tr "[A-Z]" "[a-z]" | 
   sed -e 's/[[:punct:]]*//g' -e '/^[[:space:]]*$/d' > moby-dick-words.txt

$ wc moby-dick-words.txt

215117 moby-dick-words.txt
$ time sort moby-dick-words.txt > moby-dick-words-sorted.txt

real    0m0.260s
user    0m0.462s
sys 0m0.004s
我们可以对文本的各个部分进行排序,比如说一次10000个单词,然后将一些艰苦的串行工作推迟到合并(
sort-m
)部分:

因此,它将文本拆分为连续的10000行块,使用parallel对每个块进行排序,然后使用
sort-m
将排序后的块合并为一个完整的排序

下一种方法是在拆分阶段而不是合并阶段进行艰苦的工作,以便通过一个简单的cat将部分结果合并在一起:

  $ rm tmp/*
  $ letters="a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9"
  $ time (
    cd tmp; 
    parallel sed -e "/^{}/w{}.txt" ../moby-dick-words.txt ::: $letters >& /dev/null;
    parallel sort {}.txt -o {}.sorted.txt ::: $letters;  
    cat *.sorted.txt > ../moby-dick-words-sorted-split.txt;
    rm *.txt )

  real  0m1.015s
  user  0m2.355s
  sys   0m0.510s
  $ diff moby-dick-words-sorted-split.txt moby-dick-words-sorted.txt
  $ uniq -c moby-dick-words-sorted-split.txt | tail
  1 zeuglodon
  1 zigzag
  5 zodiac
  1 zogranda
  4 zone
  1 zone
  2 zoned
  3 zones
  2 zoology
  1 zoroaster
在这里,我们(并行地)按行的第一个字符分割文件;分别对这些文件进行排序;然后合并是一个简单的连接


请注意,这仅用于娱乐/教育目的;gnu sort的更高版本内置了并行性(查看选项),这将比这做得更好。在中可以看到合并方法的更圆滑版本。

我意识到这是一个有点强迫的例子,但随着复杂性的增加,性能越来越差。我们得到了什么?@glennjackman什么都没有!在这些情况下,额外的文件I/O完全支配了多核带来的任何好处。通过限制启动的作业数量、使用管道而不是文件系统以及处理更大的数据,可以获得更好的作业性能,但真正使用并行排序只是一种通用技术的示例(IMHO)。使用多核排序的正确方法是使用
sort--parallel
@JonathanDursi奇妙的解释!我知道这只是出于娱乐/教育目的。但是,在集群中使用parallel是否可能与使用其他语言的map-reduce竞争呢?如果没有,我们什么时候应该使用GNU parallel?@qqibrow这就是事情变得更有趣的地方——使用(比如)GNU parallel在集群上的节点之间分发东西,然后排序——并行在节点内进行多核排序。这样,您就可以访问更多的RAM来进行排序,这样可以提高性能(不过请注意,
sort
s外部内存排序的性能非常好)。一旦一个人跨越了节点,就没有真正的理由认为gnu parallel是一种比任何其他工作岗位培养方法更糟糕的工作岗位培养方法;但并非所有用例都能很好地映射到gnu并行。避免首先使用
split
。这会毁了你的表演。改为使用--pipe part:这样,您将只读取一次文件,并且将有多个CPU执行此操作。rtfm。是 啊我应该读一下。谢谢
  $ rm tmp/*
  $ letters="a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9"
  $ time (
    cd tmp; 
    parallel sed -e "/^{}/w{}.txt" ../moby-dick-words.txt ::: $letters >& /dev/null;
    parallel sort {}.txt -o {}.sorted.txt ::: $letters;  
    cat *.sorted.txt > ../moby-dick-words-sorted-split.txt;
    rm *.txt )

  real  0m1.015s
  user  0m2.355s
  sys   0m0.510s
  $ diff moby-dick-words-sorted-split.txt moby-dick-words-sorted.txt
  $ uniq -c moby-dick-words-sorted-split.txt | tail
  1 zeuglodon
  1 zigzag
  5 zodiac
  1 zogranda
  4 zone
  1 zone
  2 zoned
  3 zones
  2 zoology
  1 zoroaster