Я уже задавал здесь вопрос относительно многопоточности внутри многопроцессорной обработки, результаты которой трудно понять, и породил еще один популярный вопрос Многопоточность V / s Многопоточность.
Я уже просматривал различные сообщения по этому поводу, но ни один из них четко не ответил, какой из них выбрать вместо другого, и даже не о методах проверки того, какой из них лучше всего подходит для вашей потребности. Из большей части сообщения я узнал, что многопоточность - это ввод-вывод, а многопоточность - это привязка к ЦП, но когда я использовал оба в случае процесса, привязанного к ЦП, результаты не в пользу гипотезы о том, что можно слепо выбрать Многопоточность для ввода-вывода и многопоточность для привязки к ЦП.
Как и в моем случае, поскольку процесс привязан к ЦП, результаты в пользу многопоточности. Я заметил, что иногда даже в процессах, связанных с процессором, многопоточность лидирует по сравнению с многопоточностью. Я ищу методологию, которая поможет мне выбрать один из них для использования?
Ниже приведен мой анализ, в котором я запускал многопроцессорный и многопоточный код на моем Intel i7, 8th Gen, 8-ядерный, 16 ГБ компьютер с использованием Python 3.7.2 (также тестировался на Python 3.8.2)
Определение необходимых функций и переменных
import numpy as np
import time
import concurrent.futures
a = np.arange(100000000).reshape(100, 1000000)
def list_double_value(x):
y = []
for elem in x:
y.append(2 *elem)
return y
def double_value(x):
return 2* x
Случай 1 (Использование функции, которая принимает список вход и умножьте каждый его элемент на 2
Многопроцессорность с использованием функции list_double_value (
Заняло 145 секунд )
t = time.time()
with concurrent.futures.ProcessPoolExecutor() as executor:
my_results = executor.map(list_double_value, a) # takes a list and double its value
print(time.time()-t)
Многопоточность с использованием функции list_double_value (
Заняло 28 секунд )
t = time.time()
with concurrent.futures.ThreadPoolExecutor() as executor:
my_results = executor.map(list_double_value, a)
print(time.time()-t)
Случай 2 (Использование функции, которая принимает значение и умножает его на 2)
Многопоточность с использованием двойного значения (
Заняло 2,73 секунды )
t = time.time()
with concurrent.futures.ProcessPoolExecutor() as executor:
my_results = executor.map(double_value, a)
print(time.time()-t)
Многопоточность с использованием двойного значения (
Заняло 0,2660 секунды )
t = time.time()
with concurrent.futures.ThreadPoolExecutor() as executor:
my_results = executor.map(double_value, a)
print(time.time()-t)
Исходя из приведенного выше анализа, каждый раз перед написанием кода для многопоточности или многопроцессорности нам нужно проверить, какие из них работают быстрее, и согласиться на это или существует ли какой-либо набор правил, которые предоставляют конкретные правила для выбора одного из них?
Также дайте мне знать, все ли эти результаты связаны с lib concurrent.futures, который я использовал. (Насчет библиотеки я тоже не уверен)