производительность awk vs си

Модератор: Модераторы разделов

Аватара пользователя
denel
Сообщения: 447
ОС: Gentoo Linux

производительность awk vs си

Сообщение denel » 28.05.2017 09:53

Доброго всем дня!
Что-то не могу окончательно разобраться: у чего производительность получится выше и ощутимо ли...
делаю

Код: Выделить всё

tcpdump udp -i eth0 -n | \
 grep --line-buffered \
 '192\.168\.0\.2[501][206]\.12[43][40]:'| \
 sed -e 's/.*\([0-5][0-9]\):\([0-5][0-9]\)\.//' | \
 awk '{
   ipnum=0
   for (ipnum in ip) {
     if (ip[ipnum] == $5) break
     ipnum++
   }
   if (ip[ipnum] != $5) ip[ipnum]=$5
   a[ipnum]=$1
   b=( a[ipnum]-aold[ipnum] )
   if ((b>500000) || (b<0)) {
     print $1 >> ""ip[ipnum]
     aold[ipnum]=a[ipnum]
   }
   fflush()
 }'

Таким образом awk распознаёт несколько адресов юникаст пакетов MPEG2, и раз в полсекунды примерно записывает что-то в файл, у которого в названии unicast ip-адрес. Если запись в файл перестаёт осуществляться в течение какого-то времени, другой скрипт бьёт тревогу о прекращении потока по данному юникаст адресу (по другим то адресам запись в файлы идёт). Система довольно слабенькая, пережившая уже несколько реинкарнаций, в связи с чем возникает потребность в максимальной оптимизации. Если написать то, что делает awk, программкой на си (пока не умею, но наверно смог бы осилить), будет ли производительность этого добра по-выше?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 13463
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: производительность awk vs си

Сообщение Bizdelnick » 28.05.2017 10:47

Будет ли производительней — зависит исключительно от того, насколько хорошо сможете осилить. Но изменится ли от этого что-то в отношении производительности всего конвейера — совершенно отдельный вопрос, ответ на который можно получить только эмпирически.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 13463
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: производительность awk vs си

Сообщение Bizdelnick » 28.05.2017 11:09

Я бы начал с того, что уменьшил объём выхлопа tcpdump. Включите фильтрацию по хосту или сети, да и, как я понимаю, опцию -q можно использовать, если содержимое пакетов не важно. grep тогда станет не нужен.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
denel
Сообщения: 447
ОС: Gentoo Linux

Re: производительность awk vs си

Сообщение denel » 28.05.2017 12:51

Bizdelnick писал(а):
28.05.2017 10:47
Будет ли производительней — зависит исключительно от того, насколько хорошо сможете осилить. Но изменится ли от этого что-то в отношении производительности всего конвейера — совершенно отдельный вопрос, ответ на который можно получить только эмпирически.

То есть при использовании такого конвейера нет категоричной разницы между тем, что это обработка в awk с тем алгоритмом, что я задал, и программой на си? И соответственно будет категоричная разница между тем, что я написал в awk и тем, что я написал был далее.... | while read -a a; do .......; done ?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 13463
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: производительность awk vs си

Сообщение Bizdelnick » 28.05.2017 13:41

denel писал(а):
28.05.2017 12:51
То есть при использовании такого конвейера нет категоричной разницы между тем, что это обработка в awk с тем алгоритмом, что я задал, и программой на си?

Разница, конечно, есть, но можно и на си наворотить такого, что будет тормознее awk. А главное — непонятно, где именно бутылочное горлышка Вашего конвейера. На grep может валиться очень много ненужного мусора, и не исключено, что оптимизировать надо начинать с этого места, тем более что это проще.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
denel
Сообщения: 447
ОС: Gentoo Linux

Re: производительность awk vs си

Сообщение denel » 28.05.2017 21:09

Bizdelnick писал(а):
28.05.2017 13:41
denel писал(а):
28.05.2017 12:51
То есть при использовании такого конвейера нет категоричной разницы между тем, что это обработка в awk с тем алгоритмом, что я задал, и программой на си?

Разница, конечно, есть, но можно и на си наворотить такого, что будет тормознее awk. А главное — непонятно, где именно бутылочное горлышка Вашего конвейера. На grep может валиться очень много ненужного мусора, и не исключено, что оптимизировать надо начинать с этого места, тем более что это проще.

я имею ввиду разницу в раз 50 хотябы :) )))
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 13463
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: производительность awk vs си

Сообщение Bizdelnick » 28.05.2017 23:25

Давайте вернёмся к началу. Вы хотите оптимизировать конвейер из 4 команд. Результат даст только оптимизация самой медленной из них. Вы точно знаете, что узким местом является именно awk? Если нет, хоть на асме перепишите — результата не будет.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
denel
Сообщения: 447
ОС: Gentoo Linux

Re: производительность awk vs си

Сообщение denel » 31.05.2017 01:15

Bizdelnick писал(а):
28.05.2017 23:25
Давайте вернёмся к началу. Вы хотите оптимизировать конвейер из 4 команд. Результат даст только оптимизация самой медленной из них. Вы точно знаете, что узким местом является именно awk? Если нет, хоть на асме перепишите — результата не будет.

Я так полагаю по сравнению с тем, с чего начинал этот мониторинг, сейчас всё довольно неплохо смог оптимизировать

Код: Выделить всё

tcpdump -u -i eth0 -n \
 net 230.1.1.0/24 or host 192.168.0.206 \
 or host 192.168.0.252 -t | \
 awk '{
   if (($4 == "230.1.1.1.1240:") ||
       ($4 == "230.1.1.2.1235:") ||
       ($4 == "230.1.1.3.1234:") ||
       ($4 == "230.1.1.5.1346:") ||
       ($4 == "192.168.0.206.1234:") ||
       ($4 == "192.168.0.252.1234:")) {
     ipnum=0
     for (ipnum in ip) {
       if (ip[ipnum] == $4) break
       ipnum++
     }
     if (ip[ipnum] != $4) ip[ipnum]=$4
     a++
     if (a>1000) {
       d=0
       while (d<length(a)) {
         c[d]=1
         d++
       }
       a=0
     }
     if (c[ipnum] != 0) {
       print "1" >> ip[ipnum]
       c[ipnum]=0
       a=0
     }
   }
   fflush()
 }'

tcpdump 1% CPU, awk 4% CPU
Если ещё уточнить свод адресов/портов tcpdump, работу awk можно ещё уменьшить. И это неплохой результат благодаря стремлению и советам. Начинал с того, что фильтровал grep, а awk всего на всего при каждом поступающем пакете по адресу записывал единицу в файл с названием этого адреса. В итоге при таком интенсивном вызове режима записи ФС, работа системы в целом очень ощутимо замедлялась. Вот на счёт условий tcpdump ещё не понял, можно ли в нём делать такие конструкции:

Код: Выделить всё

( a == 1 && b == 2 ) || ( c == 3 && ( d == 4 || e == 5 ) )

Так же интересует, как узнать, на что тратит время процессора ядро. Вот я вижу, что top показывает usr 27%, а sys 16%, по usr даёт представление, что расходует время, а вот по sys пока вообще без понятия, как это увидеть. Наверно только прекращением выполнения тех или иных задач?
Спасибо сказали:

Вернуться в «Программирование для начинающих»