проблема распараллеливания кода на одной машине - PullRequest
0 голосов
/ 22 апреля 2019

Параллельно с dask медленнее, чем последовательное кодирование.

У меня есть вложенные циклы for, которые я пытаюсь распараллелить на локальном кластере, но не могу найти правильный путь.

Я хочу распараллелить внутренний цикл.

У меня есть две большие матрицы, которые я пытаюсь перебрать и выполнить математическое вычисление для подмножества матриц. Размеры:

data_mat.shape = (38, 243863)
indicies_mat.shape (243863, 27)
idxX.shape = (19,)
idxY.shape = (19,)

seq_code:

start = datetime.datetime.now()
for i in range(num+1):
    if i == 0:
        labels = np.array(true_labels)
    else:
        labels = label_mat[i]

    idxX = list(np.where(labels == 1))
    idxY = list(np.where(labels == 2))

    ansColumn = []

    for j in range(indices.shape[0]):
        list_of_indices = [[i] for i in indices_slice]
        dataX = (data_mat[idxX, list_of_indices]).T
        dataY = (data_mat[idxY, list_of_indices]).T
        ansColumn.append(calc_func(dataX, dataY))

    if i == 0:
        ansMat = ansColumn
    else:
        ansMat = np.c_[ansMat, ansColumn]


end = datetime.datetime.now()
print(end - start)

параллельный код:

start = datetime.datetime.now()
cluster = LocalCluster(n_workers=4, processes=False)
client = Client(cluster)
for i in range(num+1):
    if i == 0:
        labels = np.array(true_labels)
    else:
        labels = label_mat[i]

    idxX = list(np.where(labels == 1))
    idxY = list(np.where(labels == 2))

    [big_future] = client.scatter([data_mat], broadcast=True)
    [idx_b] = client.scatter([idxX], broadcast=True)
    [idy_b] = client.scatter([idxY], broadcast=True)


    futures = [client.submit(prep_calc_func, idx_b, idy_b, indices[j, :], big_future) for j in range(indices.shape[0])]
    ansColumn = []

    for fut in dask.distributed.client.as_completed(futures):
        ansColumn.append(fut.result())

    if i == 0:
        ansMat = ansColumn
    else:
        ansMat = np.c_[ansMat, ansColumn]


end = datetime.datetime.now()
print(end - start)

вспомогательная функция:

def = prep_calc_func(idxX, idxY, subset_of_indices, data_mat):
    list_of_indices = [[i] for i in indices_slice]
    dataX = (data_mat[idxX, subset_of_indices]).T
    dataY = (data_mat[idxY, subset_of_indices]).T
    ret_val = calc_func(dataX, dataY)
    return ret_val

локальный компьютер: MacBook Pro (Retina, 13-дюймовый, середина 2014 г.) Процессор: 2,6 ГГц Intel Core i5

hw.physicalcpu: 2 hw.logicalcpu: 4

Память: 8 ГБ, 1600 МГц, DDR3

когда я выполняю код seq, для завершения требуется 01:52 минуты (менее 2 минут)

но когда я пытаюсь выполнить параллельный код, это занимает намного больше 15 минут. (независимо от того, какой метод я использую: вычисления, результат и client.submit или dask с задержкой)

(я предпочитаю использовать распределенный пакет dask, потому что на следующем этапе, возможно, также будут использоваться удаленные кластеры.)

Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 27 апреля 2019

Есть много причин, почему что-то может быть медленным.Там может быть много общения.Ваши задачи могут быть слишком маленькими (напомним, что накладные расходы Dask составляют около 1 мс на задачу), или что-то совсем другое.Для получения дополнительной информации о понимании производительности в Dask я рекомендую следующие документы:

...