Чтобы предположить улучшение скорости из-за какой-либо формы мульти-вычислений, вы должны предположить, что либо несколько задач на базе ЦП выполняются одновременно на нескольких вычислительных ресурсах (обычно ядрах процессора), либо что не все задачи зависят от одновременного использования один и тот же ресурс - то есть некоторые задачи могут зависеть от одного компонента системы (например, дискового хранилища), в то время как некоторые задачи зависят от другого (получение связи от периферийного устройства), а для других может потребоваться использование ядер процессора.
Первый сценарий часто называют «параллельным» программированием. Второй сценарий часто называют «параллельным» или «асинхронным» программированием, хотя «параллельный» иногда также используется для обозначения случая простого разрешения операционной системе чередовать выполнение нескольких задач, независимо от того, должно ли такое выполнение размещать последовательно или если для параллельного выполнения можно использовать несколько ресурсов. В этом последнем случае «параллельный» обычно относится к способу написания выполнения в программе, а не с точки зрения фактической одновременности выполнения задачи.
Обо всем этом очень легко говорить с неявными предположениями. Например, некоторые быстро заявляют, что «асинхронный ввод-вывод будет быстрее, чем многопоточный ввод-вывод». Это утверждение сомнительно по нескольким причинам. Во-первых, может случиться так, что некоторая данная структура асинхронного ввода-вывода реализована именно с многопоточностью, и в этом случае они являются одним и тем же, и не имеет смысла говорить, что одна концепция «быстрее, чем другая». ,
Во-вторых, даже в случае однопоточной реализации асинхронной инфраструктуры (например, однопоточного цикла событий) вы все равно должны делать предположения о том, что делает этот цикл. Например, одна глупая вещь, которую вы можете сделать с однопоточным циклом обработки событий, - это запросить его асинхронно выполнить две разные задачи, связанные исключительно с процессором. Если бы вы сделали это на машине только с идеализированным одноядерным процессором (игнорируя оптимизацию современного оборудования), то выполнение этой задачи «асинхронно» на самом деле не было бы иначе, чем выполнение ее с двумя независимо управляемыми потоками или с одним единственным процессом - - разница может сводиться к переключению контекста потока или оптимизации расписания операционной системы, но если обе задачи передаются процессору, это будет одинаково в любом случае.
Полезно представить себе множество необычных или глупых случаев, с которыми вы можете столкнуться.
«Асинхронный» не обязательно должен быть параллельным, например, как указано выше: вы «асинхронно» выполняете две задачи, связанные с ЦП, на машине с ровно одним процессорным ядром.
Многопоточное выполнение не обязательно должно быть одновременным: вы создаете два потока на машине с одним ядром процессора или просите два потока получить любой другой вид дефицитного ресурса (представьте, например, сетевая база данных, которая может установить только один соединение за раз). Выполнение потоков может чередоваться, хотя планировщик операционной системы считает нужным, но их общее время выполнения не может быть уменьшено (и будет увеличено из-за переключения контекста потока) на одном ядре (или, в более общем смысле, если вы создаете больше потоков, чем есть ядер для их запуска или иметь больше потоков, запрашивающих ресурс, чем то, что ресурс может поддерживать). То же самое касается и многопроцессорной обработки.
Таким образом, ни асинхронный ввод-вывод, ни многопоточность не должны обеспечивать какого-либо повышения производительности с точки зрения времени выполнения. Они могут даже замедлить работу.
Однако, если вы определяете конкретный вариант использования, например, конкретную программу, которая одновременно выполняет сетевой вызов для извлечения данных из подключенного к сети ресурса, такого как удаленная база данных, а также выполняет некоторые вычисления, связанные с локальным процессором, тогда вы можете начать рассуждать о различия в производительности между двумя методами с учетом конкретного предположения об оборудовании.
Вопросы, которые нужно задать: сколько вычислительных шагов мне нужно выполнить и сколько независимых систем ресурсов существует для их выполнения? Существуют ли подмножества вычислительных шагов, которые требуют использования независимых подкомпонентов системы и могут извлечь выгоду из одновременного использования? Сколько у меня процессорных ядер и каковы накладные расходы на использование нескольких процессоров или потоков для выполнения задач на отдельных ядрах?
Если ваши задачи в значительной степени зависят от независимых подсистем, то асинхронное решение может быть хорошим. Если количество потоков, необходимых для его обработки, будет большим, так что переключение контекста станет нетривиальным для операционной системы, тогда однопоточное асинхронное решение могло бы быть лучше.
Всякий раз, когда задачи привязаны к одному и тому же ресурсу (например, нескольким потребностям одновременного доступа к одной и той же сети или локальному ресурсу), многопоточность, вероятно, приведет к неудовлетворительным накладным расходам, а в то время как однопоточная асинхронность может привести к меньшим накладным расходам в таком ресурсе: ограниченная ситуация, она тоже не может привести к ускорению. В таком случае единственный вариант (если вы хотите ускорения) - сделать несколько копий этого ресурса доступными (например, несколько процессорных ядер, если дефицитным ресурсом является ЦП; лучшая база данных, которая поддерживает больше одновременных подключений, если ограниченный ресурс - база данных с ограничением количества соединений и т. д.)
Другими словами, разрешение операционной системе чередовать использование одного ресурса для двух задач не может быть быстрее, чем просто позволить одной задаче использовать ресурс, в то время как другая ждет, а затем позволить второй задаче завершиться последовательно. Кроме того, затраты планировщика на чередование означают, что в любой реальной ситуации это фактически вызывает замедление. Не имеет значения, происходит ли чередование использования ЦП, сетевого ресурса, ресурса памяти, периферийного устройства или любого другого системного ресурса.