Как оптимизировать параллель GNU для этого использования?

У меня недостаточно баллов для комментариев, но ответ Чарли помог мне решить проблему с настройкой маскировки. Однако я не мог удалить устройство, так как в моем случае это было исходящее соединение ppp0.

В данном случае мне помогло уменьшить mtu других клиентов до значения устройства ppp0 (1492 )либо напрямую, либо через конфигурацию dhcpd. В этом случае симптомами были проблемы с рукопожатиями TLS при попытке получить электронные письма (только с некоторых серверов )и с потоковой передачей видео от других клиентов.

0
25.01.2020, 17:18
3 ответа

GNU Parallel тратит 2 -10 мс на каждое задание. Его можно немного уменьшить, используя -u, но это означает, что вы можете получить смешанный вывод из разных заданий.

GNU Parallel не идеален, если ваши задания находятся в диапазоне мс и время выполнения имеет значение. :Накладные расходы часто будут слишком большими.

Вы можете распределить нагрузку на несколько ядер, запустив несколько GNU Parallels:

seq 5000 | parallel --pipe --round-robin -N100 parallel isprime

Вы по-прежнему платите накладные расходы, но теперь у вас, по крайней мере, есть больше ядер для оплаты.

Лучшим способом было бы изменить isprimeтак, чтобы он принимал несколько входных данных и, следовательно, выполнялся дольше:

isprime() {
  _isprime () {
      local n=$1
      ((n==1)) && return 1
      for ((i=2;i<n;i++)); do
          if ((n%i==0)); then
              return 1
          fi
      done
      printf '%d\n' "$n"
  }
  for t in "$@"; do
    _isprime $t
  done
}
export -f isprime

seq 5000 | parallel -X isprime
# If you do not care about order, this is faster because higher numbers always take more time
seq 5000 | parallel --shuf -X isprime

1
29.01.2020, 09:03

Путем изменения основного цикла for:

for ((f=1;f<=$1;f+=2)); do
    isprime $f &
    isprime $((f+1))
done

работает немного быстрее

]# time./jj.sh 5000 |wc
    669     669    3148

real    0m2.537s
user    0m8.109s
sys     0m1.374s

, чем без&:

real    0m5.758s
user    0m5.761s
sys     0m0.007s

или только с фоновыми вызовами&:

real    0m3.298s
user    0m10.743s
sys     0m1.869s

Итак, в то время как амперсанд перенес вас с 28 на 5, я перешел с 5 на 3.

Я также пробовал 2 с амперсандом и 1 без, но это уже становится медленнее.


]# time./jj.sh 5000 |wc
^C

real    0m17.668s
user    0m17.576s
sys     0m1.344s

Резкое замедление (см. ^C ), если амперсанд стоит только во втором вызове:

for ((f=1;f<=$1;f+=2)); do
    isprime $f
    isprime $((f+1)) &
done

Это кажется немного запутанным.


Используя найденные простые числа только как делители, можно ускориться в 20 раз:

max=5000
max2=75
primes=('3')
echo '2'; echo '3'

for ((n=5; n<max; n+=2))
do  size=${#primes[@]}
    for ((pi=0; pi<=$size; pi++))
    do  p=${primes[$pi]}
        if (( $n % $p == 0 ))
        then break
        fi
        if (( $p * $p > $n ))
        then echo $n
             (( $n < $max2 )) && primes+=("$n")
             break
        fi
    done
done

Это дает:

]# time. prim.sh |wc
    669     669    3148

real    0m0.126s
user    0m0.142s
sys     0m0.001s

И то же самое в perl:

]# time perl prim.pl | wc
    668    1336    6486

real    0m0.008s
user    0m0.009s
sys     0m0.001s

(первая строка выглядит как *** 3, поэтому wcвывод нормальный)

Но этот алгоритм труднее распараллелить:isprime()должен иметь доступ к (растущему )списку простых чисел (вплоть до sqrt ).

Возможно,factor(команда, борющаяся с разделом 6 :), была бы полезна в качестве стандартной функциональной единицы. Потом можно кормить разными «кусочками».

]# time seq 2 5000 |factor |sed '/.* /d' |cut -f1 -d':' |wc 
    669     669    3148

real    0m0.008s
user    0m0.014s
sys     0m0.005s

Команда sedудаляет строки, содержащие более одного пробела (, т.е. более одного множителя ).

Но опять же, это слишком быстро, чтобы помочь:

]# time seq 900000000002 900000005000 | factor  |wc
   4999   26848  163457

real    0m0.031s
user    0m0.035s
sys     0m0.003s
0
28.01.2020, 02:38

Я не буду упоминать оптимизацию is_primeитераций для квадратного _корня из (n ).

Я подозреваю, что версия с параллельным запуском тратит значительное количество времени на запуск процессов. Поэтому разбейте его на более крупные куски. например. n/Число _из _процессоров должно быть самым быстрым (, если каждый фрагмент занимает одинаковое время ). Попробуйте несколько размеров кусков, посмотрите, что произойдет.

Вам придется адаптировать свой скрипт, чтобы он уменьшался и увеличивался.

напр. организовать параллельную работу (, если у вас 5 ядер ).

./script    0 1000 &
./script 1000 1000 &
./script 2000 1000 &
./script 3000 1000 &
./script 4000 1000 &
1
28.01.2020, 02:38

Теги

Похожие вопросы