0

Я написал эту программу, чтобы правильно изучить, как использовать многопоточность. Я хочу, чтобы реализовать что-то похожее на это в моей собственной программе:Многопоточное приложение 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 - это путь.

+1

Возможный дубликат [Производительность кода на Python уменьшается с потоком] (http://stackoverflow.com/questions/6821477/python-code-performance-decreases-with-threading) – Tagc

+1

Вы знаете, что вы начинаете 10 000 потоков? –

+0

@KlausD. Прости, я пропустил это. Я обновил код и вывод. По-прежнему такая же проблема, несмотря на то, что не начинается это смешное количество потоков! – LiquidFunk

ответ

0

Количество вопросов здесь довольно ... многочисленное. Слишком много (! Системы) нить, которые делают слишком мало работу, то GIL и т.д. Это то, что я считаю очень хорошее введение в параллельность в Python:

https://www.youtube.com/watch?v=MCs5OvhV9S4

Живого кодирование является удивительным.

+0

Я обновил код и вывел моменты перед публикацией. Безумное количество потоков было удалено! Я проверю ссылку, хотя, спасибо. – LiquidFunk