Как распараллелить два вложенных цикла? - PullRequest
0 голосов
/ 13 декабря 2018

Я хочу распараллелить два вложенных цикла в Python 2.7, но безуспешно.Я не знаю, как приблизиться к определению того, что распараллеливать.

Во всяком случае, вот код одного процессора:

import time

i = [int(x) for x in range(10000)]
j = [int(x) for x in range(10000, 20000)]

print len(i)
print len(j)

def sum(niz1,niz2):
    suma=[]
    for i in range(len(niz1)):
    suma1=0
        for j in range(len(niz2)):
            suma1=suma1+niz1[i]*niz2[j]
        suma.append(suma1)
    return suma

start_t0=time.time()
suma=sum(i, j)
print len(suma)

print ("Time:  %s seconds " % (time.time() - start_t0))

Я хочу иметь распараллеливание для первого массива.Как это сделать, так как этот массив нужен и во втором цикле?

Простое объяснение и пример кода очень помогли бы.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Первый шаг с вычислениями больших массивов значений в Python должен заключаться в том, чтобы реализовать его в numpy.Таким образом, вы можете воспользоваться векторизацией NumPy.С помощью приведенного ниже сценария мне удалось выполнить тот же расчет за ~ 15 микросекунд вместо 9 секунд в вашей версии (почти на 1000000x быстрее).

import numpy as np
i = np.arange(10000, dtype=np.int64)
j = np.arange(10000, 20000, dtype=np.int64)
suma = i * j.sum()

Это, вероятно, не ваш настоящий расчет, поэтому вам следуетподумайте, как это сделать в вашем случае использования.

0 голосов
/ 13 декабря 2018

Пара мыслей:

  1. Я надеюсь, что ваш реальный расчет сложнее, чем тот, который вы опубликовали.Если это не так, просто вычислите сумму niz2 один раз, а затем умножьте каждый элемент niz1 на эту сумму, чтобы получить вектор результата.

  2. (Предполагая, что реальный вариант использованияявляется более сложным.) Python не быстр для вычислений с привязкой к процессору.При обработке большого числа чисел вы должны использовать библиотеки типа numpy.Операции Numpy реализованы на C и, следовательно, НАМНОГО быстрее, чем обычные реализации Python.

  3. (Предполагается, что numpy не вариант.) В Python есть глобальная блокировка интерпретатора (GIL)Это гарантирует, что (кроме задач ввода-вывода) одновременно активен только один поток.Это означает, что для вычислений использование нескольких потоков не увеличит время вычислений.Единственный способ добиться истинного распараллеливания - это использовать несколько процессов (import multiprocessing), но тогда копирование результатов вычислений между процессами может стать узким местом.

Итак, попробуйте оптимизироватьсначала выполнение ядра. Использование numpy уже может решить 80% сценариев использования. Распараллеливать только в том случае, если этих оптимизаций недостаточно, и не ожидать, что улучшения будут существенными.

Помогает ли это?

...