Что означают термины "связанный с процессором" и "связанный с вводом / выводом"?
Что означают термины "связанный с процессором" и "связанный с вводом / выводом"?
9 ответов
Это довольно интуитивно понятно:
Программа привязана к ЦП, если она будет работать быстрее, если бы ЦП был быстрее, то есть она тратит большую часть своего времени, просто используя ЦП (делая вычисления). Программа, которая вычисляет новые цифры π, как правило, будет привязана к процессору, это просто сжатие чисел.
Программа связана с вводом / выводом, если она будет работать быстрее, если подсистема ввода / вывода будет быстрее. Какая именно система ввода / вывода подразумевается, может варьироваться; Я обычно ассоциирую это с диском, но, конечно, сеть или общение в целом тоже распространены. Программа, которая просматривает огромный файл для некоторых данных, может стать связанной с вводом / выводом, поскольку узким местом является чтение данных с диска (на самом деле, этот пример, возможно, является старомодным в наши дни с сотнями МБ / с). из SSD).
CPU Bound означает, что скорость, с которой идет процесс, ограничена скоростью процессора. Задача, которая выполняет вычисления с небольшим набором чисел, например, умножением небольших матриц, скорее всего, связана с процессором.
Ограничениеввода / вывода означает, что скорость, с которой происходит процесс, ограничена скоростью подсистемы ввода / вывода. Задача, которая обрабатывает данные с диска, например, подсчет количества строк в файле, скорее всего, связана с вводом / выводом.
Ограничениепамяти означает, что скорость, с которой идет процесс, ограничена объемом доступной памяти и скоростью доступа к этой памяти. Задача, которая обрабатывает большие объемы данных в памяти, например, умножает большие матрицы, скорее всего, будет связана с памятью.
Кэш-привязка означает скорость, с которой прогресс процесса ограничен объемом и скоростью доступного кэша. Задача, которая просто обрабатывает больше данных, чем помещается в кеш, будет привязана к кешу.
Bound I/O будет медленнее, чем Bound Memory, будет медленнее, чем Cache Bound, будет медленнее, чем CPU Bound.
Решение быть связанным с вводом / выводом не обязательно, чтобы получить больше Памяти. В некоторых ситуациях алгоритм доступа может быть разработан с учетом ограничений ввода-вывода, памяти или кэша. См. Кэширующие забывающие алгоритмы.
многопоточность - это тот случай, когда различие имеет значение, как описано в примерах ниже.
Пример ввода-вывода ОЗУ: векторная сумма
Рассмотрим программу, которая суммирует все значения одного вектора:
#define SIZE 1000000
unsigned int is[SIZE];
unsigned int sum = 0;
size_t i = 0;
for (i = 0; i < SIZE; i++)
/* Each one of those requires a RAM access! */
sum += is[i]
Распараллеливание того, что разделение массива поровну для каждого из ваших ядер имеет ограниченную полезность на обычных современных настольных компьютерах. Тест C++ по адресу: https://github.com/cirosantilli/algorithm-cheat/blob/ea16f6bba12e7dcc32c0cbbbcdc74bcc2fd2d05b/src/cpp/interactive/sum_array_parallel.cpp
Протестировано на GCC 5.2.1, Ubuntu 15.10 с 4-ядерным процессором Intel i5-3210M, Lenovo T430. Пример типичных результатов (переменные, поскольку многопоточные):
Time N Threads Comment
--------- ---------- --------
0.045962 none
0.0487619 1 Worse than 0 threads because of startup overhead.
0.0329526 2
0.0302511 3
0.0232993 4 Best time. Only about 2x as fast.
0.0281021 5 Worse than 4 threads because we don't have
that many cores, which generate overhead.
Расчет не был в 4 раза быстрее, чем ожидалось с 4 потоками!
Причина в том, что все процессоры совместно используют одну шину памяти, соединяющуюся с RAM:
CPU 1 --\ Bus +-----+
CPU 2 ---\__________| RAM |
CPU 3 ---/ +-----+
CPU 4 --/
поэтому узким местом становится шина памяти, а не процессор.
Это происходит потому, что добавление двух чисел занимает один цикл ЦП, а чтение памяти занимает около 100 циклов ЦП в аппаратном обеспечении 2016 года.
Таким образом, работа процессора, выполняемая на байт входных данных, слишком мала, и мы называем это процессом, связанным с вводом-выводом.
Единственный способ ускорить дальнейшие вычисления - это ускорить индивидуальный доступ к памяти с помощью нового аппаратного обеспечения памяти, например, многоканальной памяти.
Например, обновление до более быстрой тактовой частоты процессора не будет очень полезным.
Другие примеры
Умножение матриц связано с ЦП ОЗУ и ГП. Вход содержит:
2 * N**2
номера, но:
N ** 3
умножения сделаны, и этого достаточно, чтобы распараллеливание стоило того для большого практического N.
Вот почему такие библиотеки:
существовать.
Использование кэша имеет большое значение для скорости реализации. Посмотрите, например, этот пример сравнения дидактического графического процессора.
Графические процессоры имеют узкое место при передаче данных в ЦП.
Они спроектированы таким образом, что выходные данные рендеринга (прямоугольник пикселей) могут быть выведены непосредственно в видеопамять, чтобы избежать циклического обращения процессора.
Сеть является прототипом IO-связанного примера.
Даже когда мы отправляем один байт данных, для достижения цели все равно требуется много времени.
Распараллеливание небольших сетевых запросов, таких как HTTP-запросы, может значительно повысить производительность.
Если сеть уже загружена (например, загружается торрент), распараллеливание может увеличить задержку (например, вы можете загрузить веб-страницу "одновременно").
Фиктивная операция, связанная с процессором C++, которая принимает одно число и много его хрустит:
Как узнать, связаны ли вы с процессором или IO
IO без ОЗУ, связанный как диск, сеть: ps aux
то если CPU% / 100 < n threads
, Если да, вы связаны с IO, например, блокировка read
Они просто ждут данных, и планировщик пропускает этот процесс. Затем используйте дополнительные инструменты, такие как sudo iotop
решить, какой именно IO является проблемой именно.
Граница ОЗУ: трудно сказать, так как время ожидания ОЗУ включено в CPU%
измерения. Возможно, лучшее, что вы можете сделать, это оценить ошибки в кеше.
Смотрите также:
Ограничение ЦП означает, что программа является узким местом ЦПУ или центральным процессором, в то время как ограничение В / В означает, что программа является узким местом из-за ввода-вывода или ввода / вывода, таких как чтение или запись на диск, сеть и т. Д.
В общем, при оптимизации компьютерных программ стараются найти узкое место и устранить его. Знание того, что ваша программа связана с процессором, помогает, так что не нужно без необходимости оптимизировать что-то еще.
[Под "узким местом" я подразумеваю то, что заставляет вашу программу работать медленнее, чем это было бы в противном случае.]
Другой способ выразить ту же идею:
Если ускорение процессора не ускоряет вашу программу, это может быть связано с вводом / выводом.
Если ускорение ввода-вывода (например, использование более быстрого диска) не помогает, возможно, ваша программа связана с процессором.
(Я использовал "может быть", потому что вам нужно учитывать другие ресурсы. Одним из примеров является память).
Когда ваша программа ожидает ввода-вывода (например, чтение / запись на диск или чтение / запись по сети и т. Д.), Процессор может выполнять другие задачи, даже если ваша программа остановлена. Скорость вашей программы будет в основном зависеть от того, насколько быстро может произойти ввод-вывод, и если вы хотите ускорить ее, вам нужно будет ускорить ввод-вывод.
Если ваша программа выполняет много программных инструкций и не ожидает ввода-вывода, то она называется связанной с процессором. Ускорение процессора заставит программу работать быстрее.
В любом случае, ключ к ускорению программы может заключаться не в ускорении аппаратного обеспечения, а в оптимизации программы для уменьшения количества операций ввода-вывода или ЦП, в которых она нуждается, или в том, чтобы она выполняла ввод-вывод, в то время как она также интенсивно использует ЦП. вещи.
Процессы, связанные с вводом-выводом: тратите больше времени на ввод-вывод, чем на вычисления, много коротких циклов ЦП. Процессы, связанные с процессором: тратить больше времени на вычисления, мало очень длинных циклов процессора
Посмотрите, что говорит Microsoft.
Ядро асинхронного программирования - это объекты Task и Task, которые моделируют асинхронные операции. Они поддерживаются ключевыми словами async и await. В большинстве случаев модель довольно проста:
Для кода с привязкой к вводу-выводу вы ожидаете операции, которая возвращает Task или Task внутри асинхронного метода.
Для кода, привязанного к ЦП, вы ждете операции, которая запускается в фоновом потоке с помощью метода Task.Run.
Ключевое слово await - вот где происходит волшебство. Он передает управление вызывающей стороне метода, выполнившего ожидание, и в конечном итоге позволяет пользовательскому интерфейсу быть гибким, а сервис - гибким.
Пример ограничения ввода-вывода: загрузка данных из веб-службы
private readonly HttpClient _httpClient = new HttpClient();
downloadButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI as the request
// from the web service is happening.
//
// The UI thread is now free to perform other work.
var stringData = await _httpClient.GetStringAsync(URL);
DoSomethingWithData(stringData);
};
Пример с привязкой к ЦП: выполнение расчета для игры
private DamageResult CalculateDamageDone()
{
// Code omitted:
//
// Does an expensive calculation and returns
// the result of that calculation.
}
calculateButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI while CalculateDamageDone()
// performs its work. The UI thread is free to perform other work.
var damageResult = await Task.Run(() => CalculateDamageDone());
DisplayDamage(damageResult);
};
В приведенных выше примерах показано, как можно использовать async и await для работы с привязкой к вводу-выводу и ЦП. Ключевым моментом является то, что вы можете определить, когда задание, которое вам нужно выполнить, связано с вводом-выводом или с привязкой к ЦП, поскольку это может сильно повлиять на производительность вашего кода и потенциально может привести к неправильному использованию определенных конструкций.
Перед написанием кода вам следует задать два вопроса:
Будет ли ваш код "ждать" чего-то, например данных из базы данных?
- Если ваш ответ "да", то ваша работа связана с вводом-выводом.
Будет ли ваш код выполнять очень дорогостоящие вычисления?
- Если вы ответили "да", то ваша работа зависит от ЦП.
Если ваша работа связана с вводом- выводом, используйте async и ждите без Task.Run. Вы не должны использовать библиотеку параллельных задач. Причина этого описана в статье Async in Depth.
Если ваша работа связана с процессором и вы заботитесь о быстродействии, используйте async и await, но запускайте работу в другом потоке с помощью Task.Run. Если работа подходит для параллелизма и параллелизма, вам также следует рассмотреть возможность использования библиотеки параллельных задач.
Граница ввода / вывода относится к условию, в котором время, необходимое для завершения вычисления, определяется главным образом периодом, затраченным на ожидание завершения операций ввода / вывода.
Это противоположно тому, что задача связана с процессором. Это обстоятельство возникает, когда скорость, с которой запрашиваются данные, ниже, чем скорость, с которой они потребляются, или, другими словами, больше времени затрачивается на запрос данных, чем на их обработку.
Приложение связано с ЦП, когда производительность арифметических / логических операций / операций с плавающей запятой (A/L/FP) во время выполнения в основном близка к теоретической пиковой производительности процессора (данные предоставлены производителем и определяются характеристиками процессор: количество ядер, частота, регистры, ALU, FPU и т. д.).
В реальных приложениях очень трудно достичь производительности быстрого просмотра, не говоря уже о невозможности. Большинство приложений обращаются к памяти на различных этапах выполнения, и процессор не выполняет операции A / L / FP в течение нескольких циклов. Это называется ограничением фон Неймана из-за расстояния, которое существует между памятью и процессором.
Если вы хотите достичь максимальной производительности ЦП, можно попробовать повторно использовать большую часть данных в кэш-памяти, чтобы не требовать данные из основной памяти. Алгоритм, использующий эту функцию, представляет собой умножение матрицы на матрицу (если обе матрицы могут храниться в кэш-памяти). Это происходит потому, что если размер матрицn x n
тогда тебе нужно заняться 2 n^3
операции с использованием только 2 n^2
Номера данных FP. С другой стороны, сложение матриц, например, является менее привязанным к ЦП или более привязанным к памяти приложением, чем умножение матриц, поскольку для этого требуется толькоn^2
FLOPs с одинаковыми данными.
На следующем рисунке показаны FLOP, полученные с помощью простых алгоритмов сложения матриц и умножения матриц в Intel i5-9300H:
Обратите внимание, что, как и ожидалось, производительность умножения матриц выше, чем при сложении матриц. Эти результаты можно воспроизвести, запустивtest/gemm
а также test/matadd
доступны в этом репозитории.
Предлагаю также посмотреть видео, данное Дж. Донгарра об этом эффекте.
Связанный процесс ввода / вывода:- Если большая часть времени жизни процесса проводится в состоянии ввода / вывода, то этот процесс является процессом, связанным с вводом / выводом. Пример:-calculator, Internet Explorer
Процесс, связанный с процессором:- Если большая часть срока службы процессируется в процессоре, то это процесс, связанный с процессором.