我正在编写一个批处理脚本来对大量数据进行排序。所有数据都是文本,但脚本将需要很长时间才能执行。我想提供一些脚本正在运行的视觉指示。我发现这个程序pv
允许您创建进度条和其他不错的CLI
进度指示器。
我的问题是这样的事情会对性能产生什么类型的影响,以及是否有其他替代方案而无需我重新发明轮子。
我已经用谷歌搜索了它,但没有发现任何令人惊讶的东西,因为我认为你只会在性能很重要的长期任务上显示进展。但我想我正在使用时钟周期,您也可以使用它来测量磁盘 I/O 或网络数据传输,其中使用几个周期来指示进度并不重要。
有任何想法吗?
PS 我也考虑过使用这个echo -ne
技巧来创建我自己的,但为了使其可行,我必须%
在每个循环上使用该运算符,并且只在第 100 个左右的循环中采取行动,但这会浪费很多计算......
答案1
通常会有(缺乏零拷贝由于额外的 IPC,将数据从一个进程复制到另一个进程,而不是直接读取文件的“主力”进程,因此是可测量的开销。管道还可能导致性能(或功能)损失其他原因:对于管道输入,进程不能seek()
使用它的输入,也不能使用mmap()
它。
一般来说,主要的性能瓶颈可能是磁盘 I/O 和 CPU 计算时间(在您的情况下这可能是密集的)。这些可能比 IPC 开销大得多,但是有许多这里的变量(CPU类型,磁盘类型和文件系统类型、可用物理 RAM、操作系统和版本、libc 和版本 — 至少)。
您可以通过一些快速测试来粗略地了解性能,注意在每次测试之前刷新磁盘缓存(我使用的是 linux,我使用这个方法)在每次测试之间。
# time ( pv -pt somethinglarge.iso | sha256sum )
[...]
real 0m8.066s
user 0m5.146s
sys 0m1.075s
# time ( sha256sum somethinglarge.iso )
[...]
real 0m7.913s
user 0m5.064s
sys 0m0.309s
请注意类似的真实用户和时间,以及显着增加系统由于额外的复制,管道案例的时间。
在某些操作系统上,特别是 Linux,您可能可以阅读每个进程的 I/O 统计信息/proc
(参见 3.3)(您需要CONFIG_TASKSTATS
在内核中启用此功能)。这不像 那样简单或灵活pv
,但开销很低。pidstat
使用这个,它可以用来显示 PID 上的实时吞吐量(速率),但作为完成指示器,它的用处不大。
类似的linux选项(这个不需要CONFIG_TASKSTATS
),给定进程和文件描述符,您可以跟踪文件描述符在/proc/PID/fdinfo/FD
(pos:
字段)中的偏移量。这是一个展示这一点的玩具脚本:
FILE=/tmp/some-large-input
SZ=$(stat -c "%s" "$FILE")
# start slow process in background
( some-slow-command $FILE ) &
PID=$!
FD=/proc/$PID/fdinfo/3 # some experimentation required
# or iterate over /proc/$PID/fd/* with readlink
# start %-ometer in background, exits when FD disappears
(
while nawk '/^pos:/{printf("%i\n",$2*100/'$SZ')}' $FD 2>/dev/null ; do
sleep 5 # adjust
done | dialog --gauge "$PID: processing $FILE ($SZ bytes)" 10 60
) &
wait $PID
if [ $? -eq 0 ]; then
echo 100 | dialog --gauge "$PID: completed $FILE ($SZ bytes)" 10 60
else
echo ...
fi
(警告:对于小文件不准确,libc stdio 缓冲会扭曲结果。)
我现在想到的其他选择:
用来
lsof
监控进程的 fd 偏移量 不完全是轻量级的,而是多平台的,并且您可以在事后在任何长时间运行的进程中启动它,但您无法这样做pv
(它也不漂亮,因为lsof
拒绝一次性给出大小和偏移量)一些黑客的东西
LD_PRELOAD
和一些跟踪数据读/写的存根,这也是多平台的,但我认为你必须编写自己的(我不知道有什么能完全做到这一点,但这里有一个我的相关回答)更新:有人不厌其烦地编写了一个通用传输监控工具简历与使用核心工具Linux 上的命令。它使用与该
/proc
fdinfo
方法类似的逻辑(如上面的 shell hack 所示)。它还具有后台模式,可以扫描 /proc 并在发现传输时报告正在进行的传输。查看相关问题是否可以查看 cp 速度和复制百分比?
答案2
在我使用该命令的情况下(主要使用 zfs 发送和接收操作),该pv
命令不会对 CPU 产生太多开销。如果您只想知道它仍在处理,您可以使用它pv
来计算通过它传输的数据。如果您想要估计完成时间,您可能需要添加一个预命令来计算要处理的数据总和pv -s <SIZE>
。这种预先计算可能会导致一些开销。