Как сделать параллельные вычисления на Python, точно указав процессор нет, я делаю задачу я? - PullRequest
0 голосов
/ 05 октября 2018

Определите следующую функцию, которая добавляет натуральные числа до того места, где вы спрашиваете.

def f(x):
    lo=0
    for i in range(x):
            lo+=i
    return(lo)

Чтобы распараллелить это с помощью multiprocessing.dummy, я написал следующее

from multiprocessing.dummy import Pool as ThreadPool
pool=ThreadPool(4)
def f_parallel(x1,x2,x3,x4):
    listo_parallel=[x1,x2,x3,x4]
    resulto_parallel=pool.map(f,listo_parallel)
    return(resulto_parallel)

Это работает, но яне вижу никакого сокращения времени вычислений.Потому что определить следующие функции, которые также сообщают время вычислений.

import time
def f_t(x):
    st=time.time()
    lob=f(x)
    st=time.time()-st
    return(lob,st)
def f_parallel_t(x1,x2,x3,x4):
    listo_parallel=[x1,x2,x3,x4]
    st=time.time()
    resulto_parallel=pool.map(f,listo_parallel)
    st=time.time()-st
    return(resulto_parallel,st)

Теперь давайте рассмотрим.для x = 10 ** 7, 9 ** 7, 10 ** 7-2, 10 ** 6, нормальное f занимает 0,53, 0,24, 0,53, 0,04 секунды.И для четырех из них f_parallel занимает 1,39 секунды !!!!!Я ожидал увидеть 0,53 секунды, потому что на компьютере, который я использовал, было 4 процессора, и я выбрал 4 в пуле.Но почему это происходит так?

Я также пытался прочитать документацию многопроцессорной библиотеки Python 3.7, но они работают, только если я наберу примеры точно так, как они там написаны.Например, рассмотрим первый пример в этом документе.Если я наберу

from multiprocessing import Pool
Pool(4).map(f,[10**7,9**7,10**7-2,10**6])

, то ничего не произойдет, и мне придется перезапустить оболочку (Ctrl + F6).

И делать это pool.map не совсем то, что я хочу, я хочу сказать,Python делать f (x_i) точно на процессоре нет.я.Поэтому я хочу знать, какая часть моих вычислений выполняется на каком процессоре на любом этапе моего программирования.

Буду признателен за любую помощь или руководство.


В случае, если кто-то не понимает, что я действительно хочу сделать с python, я загружаю скриншот из файла Maple, который я сделал прямо сейчас, и который делает именно то, что я хочу сделать с Python, иЯ спрашиваю в этом вопросе.

enter image description here

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Благодаря @FlyingTeller и @quamrana, которые ответили на мой другой вопрос , теперь я знаю, как реализовать программу python для параллельного выполнения четырех вычислений так, чтобы это занимало столько времени, сколько максимальное времячетыре отдельных вычисления.Вот исправленный код:

def f(x):
    lo=0
    for i in range(x):
            lo+=i
    return(lo)
from multiprocessing import Pool
def f_parallel(x1,x2,x3,x4):
    with Pool(processes=4) as pool:
        resulto_parallel=pool.map(f,[x1,x2,x3,x4])
    return(resulto_parallel)
import time
def f_parallel_t(x1,x2,x3,x4):
    st=time.time()
    ans=f_parallel(x1,x2,x3,x4)
    st=time.time()-st
    return(ans,st)
if __name__ == '__main__':
    print(f_parallel_t(10**7,10**6,10**7-2,9**7))

И снимок экрана с результатом, когда я его запускаю: enter image description here

0 голосов
/ 06 октября 2018

В CPython, более или менее «стандартной» реализации, только один поток может одновременно выполнять байт-код Python.Поэтому использование потоков для ускорения вычислений не будет работать в CPython.

Вместо этого вы можете использовать multiprocessing.Pool.В общем, я бы рекомендовал использовать метод пула imap_unordered вместо простого map.Первый из них начнет давать значения, как только они станут доступными, а второй возвращает список после того, как все вычисления выполнены.

Понимая суть вашего вопроса, Python не имеетНезависимый от платформы метод указывает, на каком процессоре будет запущен процесс, который он запускает.То, как работает так называемая привязка процессора , очень зависит от операционной системы, как вы можете видеть на связанной странице.Конечно, вы можете использовать subprocess для запуска одной из упомянутых служебных программ или вы можете использовать ctypes для непосредственного выполнения соответствующих системных вызовов.

...