Я написал эту программу, чтобы правильно изучить, как использовать многопоточность. Я хочу, чтобы реализовать что-то похожее на это в моей собственной программе:Многопоточное приложение Python медленнее, чем однопоточная реализация
import numpy as np
import time
import os
import math
import random
from threading import Thread
def powExp(x, r):
for c in range(x.shape[1]):
x[r][c] = math.pow(100, x[r][c])
def main():
print()
rows = 100
cols = 100
x = np.random.random((rows, cols))
y = x.copy()
start = time.time()
threads = []
for r in range(x.shape[0]):
t = Thread(target = powExp, args = (x, r))
threads.append(t)
t.start()
for t in threads:
t.join()
end = time.time()
print("Multithreaded calculation took {n} seconds!".format(n = end - start))
start = time.time()
for r in range(y.shape[0]):
for c in range(y.shape[1]):
y[r][c] = math.pow(100, y[r][c])
end = time.time()
print("Singlethreaded calculation took {n} seconds!".format(n = end - start))
print()
randRow = random.randint(0, rows - 1)
randCol = random.randint(0, cols - 1)
print("Checking random indices in x and y:")
print("x[{rR}][{rC}]: = {n}".format(rR = randRow, rC = randCol, n = x[randRow][randCol]))
print("y[{rR}][{rC}]: = {n}".format(rR = randRow, rC = randCol, n = y[randRow][randCol]))
print()
for r in range(x.shape[0]):
for c in range(x.shape[1]):
if(x[r][c] != y[r][c]):
print("ERROR NO WORK WAS DONE")
print("x[{r}][{c}]: {n} == y[{r}][{c}]: {ny}".format(
r = r,
c = c,
n = x[r][c],
ny = y[r][c]
))
quit()
assert(np.array_equal(x, y))
if __name__ == main():
main()
Как вы можете видеть из кода цель здесь заключается в распараллелить операции Math.pow (100, х [г] [с]), создав поток для каждого столбца. Однако этот код чрезвычайно медленный, намного медленнее, чем однопоточные версии.
Выход:
Multithreaded calculation took 0.026447772979736328 seconds!
Singlethreaded calculation took 0.006798267364501953 seconds!
Checking random indices in x and y:
x[58][58]: = 9.792315687115973
y[58][58]: = 9.792315687115973
Я искал через StackOverflow и нашел некоторую информацию о GIL форсирования питона байткод, который будет выполнен только на одном ядре. Однако я не уверен, что это на самом деле то, что ограничивает мое распараллеливание. Я попытался переставить параллельный цикл for, используя пулы вместо потоков. Кажется, что ничего не работает.
Python code performance decreases with threading
EDIT: Эта нить обсуждает тот же вопрос. Неужели невозможно увеличить производительность, используя многопоточность в python из-за GIL? Является ли GIL причиной моего замедления?
EDIT 2 (2017-01-18): Итак, из того, что я могу собрать после поиска в Интернете, похоже, что python действительно плохо для параллелизма. То, что я пытаюсь сделать, это parellelize функция python, используемая в нейронной сети, реализованная в tensorflow ... похоже, что добавление пользовательского op - это путь.
Возможный дубликат [Производительность кода на Python уменьшается с потоком] (http://stackoverflow.com/questions/6821477/python-code-performance-decreases-with-threading) – Tagc
Вы знаете, что вы начинаете 10 000 потоков? –
@KlausD. Прости, я пропустил это. Я обновил код и вывод. По-прежнему такая же проблема, несмотря на то, что не начинается это смешное количество потоков! – LiquidFunk