
我有一个大的〜8GB的文本文件,我需要做一些简单的过滤,然后sorting所有的行。 我在一台配有SSD和128GB RAM的28核心机器上。 我努力了
方法1
awk '...' myBigfile | sort --parallel = 56 > myBigfile.sorted
方法2
awk '...' myBigfile > myBigfile.tmp sort --parallel 56 myBigfile.tmp > myBigfile.sorted
令人惊讶的是,方法1需要11.5分钟,而方法2只需要(0.75 + 1 <2)分钟。 为什么sorting如此缓慢pipe道? 这不是平行吗?
dpkg-buildpackage错误:缺less文件(usr / include / *)
如何不覆盖以前的terminal内容
如何在xfce会话结束时执行脚本
如何在linux中将MKL库永久链接到Numpy?
运行“猫”可以加速后续文件在linux机器上的随机访问?
编辑
awk和myBigfile并不重要,这个实验可以简单地使用seq 1 10000000 | sort --parallel 56来重复 seq 1 10000000 | sort --parallel 56 (感谢@Sergei Kurenkov),我还观察到在我的机器上使用无pipe道版本的速度提高了六倍。
linux命令返回的退出状态1的含义
在C / C ++ / Java中查找USB设备的信息
在Rasperry Pi kube绒布上的Kubernetes CrashLoopBackOff和kube dns rpc错误代码= 2
在屏幕上打印消息,并同时发送到系统日志
linux工具来检查C / C ++源代码中的注释拼写
从管道读取时, sort假定文件很小,对于小文件并行则没有帮助。 要进行sort以利用并行性,您需要告诉它使用-S分配一个较大的主内存缓冲区。 在这种情况下,数据文件大约是8GB,所以你可以使用-S8G 。 但是,至少在你的系统上有128GB的主内存,方法2可能仍然会更快。
这是因为在方法2中的sort可以从文件的大小知道它是巨大的,并且它可以在文件中寻找(这对管道来说都是不可能的)。 此外,由于与这些文件大小相比,你拥有的内存非常多,所以在awk退出之前myBigfile.tmp的数据不需要写入光盘, sort就可以从缓存而不是光盘读取文件。 所以方法1和方法2(在像你有很多内存的机器上)之间的主要区别在于,方法2中的sort知道文件是巨大的,可以很容易地划分工作(可能使用seek,但我没有看在实现中),而在方法1中, sort必须发现数据是巨大的,并且在读取输入时不能使用任何并行性,因为它不能查找管道。
我认为从管道读取时排序不使用线程。
我已经使用这个命令为你的第一个案件。 而且它显示,即使被告知使用4, sort只使用1个atop实际上也表明只有一个线程在sort :
/usr/bin/time -v bash -c "seq 1 1000000 | sort --parallel 4 > bf.txt"
我已经使用这个命令你的第二个案例。 这表明排序使用2个cpu。 atop还显示有四个线程在sort :
/usr/bin/time -v bash -c "seq 1 1000000 > tmp.bf.txt && sort --parallel 4 tmp.bf.txt > bf.txt"
在你的第一个场景中,sort是一个I / O绑定的任务,它会从stdin中执行大量的read系统调用。 在第二种情况下,排序使用mmap syscalls来读取文件,避免成为I / O绑定的任务。
以下是第一和第二种情况的结果:
$ /usr/bin/time -v bash -c "seq 1 10000000 | sort --parallel 4 > bf.txt" Command being timed: "bash -c seq 1 10000000 | sort --parallel 4 > bf.txt" User time (seconds): 35.85 System time (seconds): 0.84 Percent of cpu this job got: 98% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:37.43 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resIDent set size (kbytes): 9320 Average resIDent set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 2899 Voluntary context switches: 1920 Involuntary context switches: 1323 Swaps: 0 file system inputs: 0 file system outputs: 459136 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0 $ /usr/bin/time -v bash -c "seq 1 10000000 > tmp.bf.txt && sort --parallel 4 tmp.bf.txt > bf.txt" Command being timed: "bash -c seq 1 10000000 > tmp.bf.txt && sort --parallel 4 tmp.bf.txt > bf.txt" User time (seconds): 43.03 System time (seconds): 0.85 Percent of cpu this job got: 175% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:24.97 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resIDent set size (kbytes): 1018004 Average resIDent set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 2445 Voluntary context switches: 299 Involuntary context switches: 4387 Swaps: 0 file system inputs: 0 file system outputs: 308160 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
你有更多的系统调用,如果你使用管道。
seq 1000000 | strace sort --parallel=56 2>&1 >/dev/null | grep read | wc -l 2059
没有管道的文件被映射到内存。
seq 1000000 > input strace sort --parallel=56 input 2>&1 >/dev/null | grep read | wc -l 33
内核调用在大多数情况下是瓶颈。 这就是sendfile发明的原因。
AFIAK恕我直言,在你的第一个办法首先它将做awk *** 作,然后它进行转发该 *** 作到下一个排序命令,所以这将发生在单一镜头和awk的输出将作为排序的输入在这里所以绝对要存储的值(你的input_file值)更多的内存将被采取,因为没有其他文件正在创建用于存储的值(awk的这些值将存储在内存中,awk *** 作和排序将只从那里输入)。 另一方面,在第二个命令中,正在创建一个正在被排序命令使用的新文件,因此内存不需要保存整个8 GB左右的文件,因此占用的内存会更少。
总结以上是内存溢出为你收集整理的为什么使用pipe道进行sorting(Linux命令)速度慢?全部内容,希望文章能够帮你解决为什么使用pipe道进行sorting(Linux命令)速度慢?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)