Подтвердить что ты не робот

Может ли python работать на нескольких ядрах?

Вопрос: из-за использования python для "GIL" есть python, способный одновременно работать с отдельными потоками?


информация:

После прочтения этого я довольно не уверен в том, способен ли python использовать многоядерный процессор. Как и в случае с python, очень странно думать, что у него не будет таких мощных способностей. Поэтому, чувствуя себя не уверенным, я решил спросить здесь. Если я пишу программу с несколькими потоками, будет ли она работать одновременно на нескольких ядрах?

4b9b3361

Ответ 1

Ответ: "Да, но..."

Но cPython не может, когда вы используете обычные потоки для concurrency.

Вы можете использовать что-то вроде multiprocessing, celery или mpi4py, чтобы разделить параллельную работу на другой процесс;

Или вы можете использовать что-то вроде Jython или IronPython, чтобы использовать альтернативный интерпретатор, который не имеет GIL.

Более мягкое решение - использовать библиотеки, которые не запускают GIL для тяжелых задач ЦП, например numpy могут выполнять тяжелый подъем, а не сохраняя GIL, поэтому могут продолжаться другие потоки python. Таким образом вы также можете использовать библиотеку ctypes.

Если вы не выполняете работу с ЦП, вы можете полностью игнорировать проблему GIL (вид), так как python не будет использовать GIL, пока он ждет ввода-вывода.

Ответ 2

Python threads не может использовать преимущества многих ядер. Это связано с внутренней деталью реализации, называемой GIL (глобальная блокировка интерпретатора) в реализации C python (cPython), которая почти наверняка используется вами.

Обходной путь - это multiprocessing модуль http://www.python.org/dev/peps/pep-0371/, который был разработан для этой цели.

Документация: http://docs.python.org/library/multiprocessing.html

(Или используйте параллельный язык.)

Ответ 3

CPython (классическая и распространенная реализация Python) не может иметь более одного потока, исполняющего байт-код Python в одно и то же время. Это означает, что программы, связанные с вычислением, будут использовать только одно ядро. Операции ввода-вывода и вычисления, происходящие внутри C-расширений (например, numpy), могут работать одновременно.

Другая реализация Python (например, Jython или PyPy) может вести себя по-другому, я менее четко понимаю их детали.

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

Ответ 4

Потоки разделяют процесс, и процесс выполняется на ядре, но вы можете использовать модуль многопроцессорности python для вызова ваших функций в отдельных процессах и использования других ядер, или вы можете использовать модуль подпроцесса, который может запускать ваш код и не- питон кода.

Ответ 5

пример кода, который принимает все 4 ядра на моем ubuntu 14.04, python 2.7 64 бит.

import time
import threading


def t():
    with open('/dev/urandom') as f:
        for x in xrange(100):
            f.read(4 * 65535)

if __name__ == '__main__':
    start_time = time.time()
    t()
    t()
    t()
    t()
    print "Sequential run time: %.2f seconds" % (time.time() - start_time)

    start_time = time.time()
    t1 = threading.Thread(target=t)
    t2 = threading.Thread(target=t)
    t3 = threading.Thread(target=t)
    t4 = threading.Thread(target=t)
    t1.start()
    t2.start()
    t3.start()
    t4.start()
    t1.join()
    t2.join()
    t3.join()
    t4.join()
    print "Parallel run time: %.2f seconds" % (time.time() - start_time)

результат:

$ python 1.py
Sequential run time: 3.69 seconds
Parallel run time: 4.82 seconds

Ответ 6

Я преобразовал скрипт в Python3 и запустил его на своем Raspberry Pi 3B+:

import time
import threading

def t():
        with open('/dev/urandom', 'rb') as f:
                for x in range(100):
                        f.read(4 * 65535)

if __name__ == '__main__':
    start_time = time.time()
    t()
    t()
    t()
    t()
    print("Sequential run time: %.2f seconds" % (time.time() - start_time))

    start_time = time.time()
    t1 = threading.Thread(target=t)
    t2 = threading.Thread(target=t)
    t3 = threading.Thread(target=t)
    t4 = threading.Thread(target=t)
    t1.start()
    t2.start()
    t3.start()
    t4.start()
    t1.join()
    t2.join()
    t3.join()
    t4.join()
    print("Parallel run time: %.2f seconds" % (time.time() - start_time))

python3 t.py

Sequential run time: 2.10 seconds
Parallel run time: 1.41 seconds

Для меня параллельная работа была быстрее.

Ответ 7

На Raspberry Pi 3 Модель B Rev 1.2

[email protected]:~/smart/cpu $ python2 core.py
Sequential run time: 2.34 seconds
Parallel run time: 1.74 seconds
[email protected]:~/smart/cpu $ python2.7 core.py
Sequential run time: 2.34 seconds
Parallel run time: 1.74 seconds
[email protected]:~/smart/cpu $ python3 core.py
Sequential run time: 2.32 seconds
Parallel run time: 1.74 seconds
[email protected]:~/smart/cpu $ python3.4 core.py
Sequential run time: 2.32 seconds
Parallel run time: 1.74 seconds

Ответ 8

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

Ответ 9

то же самое для меня. параллель была быстрее.

range(10000)
Sequential run time: 228.56 seconds
Parallel run time: 147.03 seconds

Raspberry Pi 3 B+
Raspbian v 4.19.57-v7+ #1244
Python v. 3.5.3
GCC v. 6.3

Во время последовательного процесса загрузка процессора достигает 25%, а во время параллельного процесса загрузка процессора достигает 100%.