У меня есть сервер Ubuntu, на котором 16 процессоров. ( nproc --all
показать мне 16
)
Я написал bash-скрипт, названный test.sh
следующим образом:
#!/bin/bash
while :
do
echo xxx
done
Я выполнил это: ./test.sh >/dev/null &
.
Затем я использовал команду top
для мониторинга использования ЦП и обнаружил, что один ЦП был использован почти на 100% из-за процесса test.sh
:
6411 me 20 0 11240 3052 2852 R 93.8 0.0 0:11.71 test.sh
%Cpu5 : 96.7 us, 3.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
Как мы видим, процесс test.sh
был назначен на 5-й ЦП, который загружен почти на 100%.
Можно ли назначить тяжелый процесс на более чем один ЦП, чтобы мы могли более эффективно использовать ЦП? Почему ОС не назначила процесс test.sh
на более чем один ЦП? Это потому, что процесс test.sh
недостаточно тяжелый или нам следует выполнить некоторую настройку для ОС, чтобы сделать это?
решение1
Один поток не может быть разделен между несколькими ядрами:
Программа должна быть написана так, чтобы иметь более одного потока (по одному на ядро), или должно быть более одной программы. Если нет, то вы не будете использовать ядра.
Написание программ для использования большего количества ядер не является тривиальной задачей, и не все проблемы могут быть распараллелены (написаны для выполнения на более чем одном ядре). Если проблема содержит 20% по существу последовательного кода, то при бесконечном количестве процессоров она будет не быстрее, чем 20% от исходного времени выполнения (увеличение скорости на 500%). Затем идут накладные расходы (связь между потоками).
Если у вас нет применения ядрам, то вам лучше продать его и купить более дешевую машину.
Каждое ядро будет иметь тонну параллелизма, чтобы иметь дело с одним потоком, но это не видно. Теперь мы боремся, чтобы сделать одно ядро хоть немного быстрее, по мере добавления ядер. Это работает хорошо поначалу.
Системы Unix (такие как Gnu/Linux, например Ubuntu) хорошо справляются с использованием дополнительных ядер, до 2→4. Windows от Microsoft получает улучшения, когда у вас есть ядро для антивирусного сканера, одно для дефрагментатора и одно для всего остального.
После этого разница будет иметь значение только в том случае, если у вас есть приложения, рассчитанные на многоядерность.
решение2
Вот примеры команд Linux, которые могут использовать несколько процессоров:
make -j
gcc -pipe
Эта make
опция особенно полезна и проста при компиляции больших проектов с gcc
.
Добавьте эту
-fopenmp
опцию в параметры сборки при вызове gcc.Попробуйте добавить следующую прагму прямо над циклами for:
#pragma omp parallel for for(i=0; i<8000000000; i++) { ptr[i] = i/10000; }
По умолчанию OpenMP создаст столько потоков, сколько ядер на вашем компьютере, и равномерно распределит между ними рабочую нагрузку.