Awk 使用nvidia smi获取最高内存消耗进程的PID

Awk 使用nvidia smi获取最高内存消耗进程的PID,awk,nvidia,Awk,Nvidia,目前我有一个小bash脚本,它总结了 所有进程的vram使用 nvidia-smi | awk '{print $6}'| awk '{ SUM += $1} END { print SUM }' 但是现在我想得到使用最多VRAM的进程的PID。 在那之后,我想用 ps -u -p $pid 当前编辑我的nvidia smi如下所示: 我想得到PID 29187,因为此PID使用最多vram3649MB +-------------------------------------------

目前我有一个小bash脚本,它总结了 所有进程的vram使用

nvidia-smi | awk '{print $6}'| awk '{ SUM += $1} END { print SUM }'
但是现在我想得到使用最多VRAM的进程的PID。 在那之后,我想用

ps -u -p $pid
当前编辑我的nvidia smi如下所示: 我想得到PID 29187,因为此PID使用最多vram3649MB

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 208...  On   | 00000000:01:00.0  On |                  N/A |
| 35%   43C    P8    36W / 250W |   5012MiB / 11016MiB |     15%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      5512      G   /usr/lib/xorg/Xorg                           257MiB |
|    0      5786      G   kwin_x11                                      77MiB |
|    0      5790      G   /usr/bin/krunner                               6MiB |
|    0      5800      G   /usr/bin/plasmashell                         114MiB |
|    0     26439      G   /usr/lib/xorg/Xorg                            73MiB |
|    0     26457      G   /usr/bin/sddm-greeter                        132MiB |
|    0     29154    C+G   .../Binaries/Linux/CarlaUE4-Linux-Shipping   619MiB |
|    0     29187      C   python                                      3649MiB |
|    0     29999      G   /opt/ros/melodic/lib/rviz/rviz                62MiB |
+-----------------------------------------------------------------------------+
或者,作为图像:

它工作的最终脚本

sum=$(nvidia-smi | awk 'NR>14{SUM+=$6} NR>14 && 
0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3} END{printf SUM;}')

maxpid=$(nvidia-smi | awk 'NR>14{SUM+=$6} NR>14 && 
0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3} END{printf MAXPID;}')

if [ $sum -lt 8000 ]
then
    hostname | tr -d '\n'
    echo ' 'AVAILABLE vram  $sum 
else 
    hostname | tr -d '\n'
    user=$(ps -u -p $maxpid| awk '{print$1}'| awk 'FNR == 2 {print}')
    echo ' 'false, $user is responsible
fi
您可以将两个awk语句组合在一起,还可以解决将驱动程序版本中的数字添加到总数中的问题,如下所示:

nvidia-smi | awk 'NR>14{SUM+=$6}END{print SUM}'
只有当行大于您关心的数据所在的第14行时,才会考虑该行

添加一些逻辑以获取最大值并打印流程:

nvidia-smi | awk 'NR>14{SUM+=$6} NR>14 && 0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3} END{print SUM,MAXPID,MAXSTRING}'
这将打印出总和、最大GPU内存使用量的PID和该内存使用量

不过,如果GPU内存使用可以在MiB和KiB之间切换单元,则会出现这种情况

您可以将两个awk语句组合起来,还可以解决将驱动程序版本中的数字添加到总数中的问题,如下所示:

nvidia-smi | awk 'NR>14{SUM+=$6}END{print SUM}'
只有当行大于您关心的数据所在的第14行时,才会考虑该行

添加一些逻辑以获取最大值并打印流程:

nvidia-smi | awk 'NR>14{SUM+=$6} NR>14 && 0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3} END{print SUM,MAXPID,MAXSTRING}'
这将打印出总和、最大GPU内存使用量的PID和该内存使用量


不过,如果GPU内存使用可以在MiB和KiB之间切换单元,则会出现这种情况

为了更有效地解析所有SI公制单位KiB和GiB,您可以执行以下操作。这需要GNU awk来实现数组排序功能

awk '
$6 ~ /[M|K|G]iB/ {
    if ( index( $6, "KiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 }
    if ( index( $6, "MiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 * 1024 }
    if ( index( $6, "GiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 * 1024 * 1024 }
    usage += ram
    map[$3] = ram
}
END {
    PROCINFO["sorted_in"]="@val_num_desc"
    printf "Total RAM Usage = %s\n",((usage/1024)/1024)"MiB"
    for (i in map) {
        printf "Highest RAM Usage PID = %d Value = %s\n", i, ((map[i]/1024)/1024)"MiB"
        break
    }
}'

为了更有效地解析所有SI公制单位KiB和GiB,您可以执行以下操作。这需要GNU awk来实现数组排序功能

awk '
$6 ~ /[M|K|G]iB/ {
    if ( index( $6, "KiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 }
    if ( index( $6, "MiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 * 1024 }
    if ( index( $6, "GiB" ) ) { gsub(/[^0-9]/, "", $6); ram = ($6+0) * 1024 * 1024 * 1024 }
    usage += ram
    map[$3] = ram
}
END {
    PROCINFO["sorted_in"]="@val_num_desc"
    printf "Total RAM Usage = %s\n",((usage/1024)/1024)"MiB"
    for (i in map) {
        printf "Highest RAM Usage PID = %d Value = %s\n", i, ((map[i]/1024)/1024)"MiB"
        break
    }
}'

请您在您的帖子中发布nvidia smi的输出并让我们知道,这样我们就可以更好地理解这个问题了。awk'{print$6}'| awk'{SUM+=$1}END{print SUM}并没有给您一个好的总数。你能在你的帖子中发布nvidia smi的输出并让我们知道,这样我们就可以更好地理解这个问题了。awk'{print$6}'| awk'{SUM+=$1}END{print SUM}并没有给你一个好的总数。这里也是对驱动程序版本的总结。首先,感谢您提供这段代码。但是我很难从中获得用户。目前我的代码是这样的。责备和羞辱{echo责备用户ps-u-p$1}nvidia smi|awk'NR>14{SUM+=$6}NR>14&&0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3}END{如果SUM<11000打印融合vram=SUM\n;否则就责备我错过了那一步。您可以将pid存储到一个变量,如pid=$nvidia smi | awk'NR>14{SUM+=$6}NR>14&&0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3}END{print MAXPID},然后在下一个命令中使用它,如ps-u-p$pid。你也可以通过管道连接到xargs,然后用它在一个长命令中将pid转换到ps,但是如果出现任何错误,那么调试就会变得很困难。谢谢,是的,我用xargs完成了,然后它就可以工作了,但问题是,我想用if-else来完成。所以我不想总是打印用户。我编辑了我的问题,明白了。我会让awk将sum和maxpid解析都打印到它们自己的shell变量中。然后,你可以在外壳中做你的if,这样做更有意义。比如使用awk解析和计算文件,使用bash或其他工具处理生成的逻辑。但是我很难从中获得用户。目前我的代码是这样的。责备和羞辱{echo责备用户ps-u-p$1}nvidia smi|awk'NR>14{SUM+=$6}NR>14&&0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3}END{如果SUM<11000打印融合vram=SUM\n;否则就责备我错过了那一步。您可以将pid存储到一个变量,如pid=$nvidia smi | awk'NR>14{SUM+=$6}NR>14&&0+$6>MAX{MAX=0+$6;MAXSTRING=$6;MAXPID=$3}END{print MAXPID},然后在下一个命令中使用它,如ps-u-p$pid。你也可以通过管道连接到xargs,然后用它在一个长命令中将pid转换到ps,但是如果出现任何错误,那么调试就会变得很困难。谢谢,是的,我用xargs完成了,然后它就可以工作了,但问题是,我想用if-else来完成。所以我不想总是打印用户。我编辑了我的问题,明白了。我会让awk将sum和maxpid解析都打印到它们自己的shell变量中。然后,你可以在外壳中做你的if,这样做更有意义。例如,使用awk解析和计算文件,使用bash或其他方法处理生成的逻辑。