IT story

파이썬은 다중 코어에서 실행할 수 있습니까?

hot-time 2020. 12. 30. 19:16
반응형

파이썬은 다중 코어에서 실행할 수 있습니까?


질문 : 파이썬이 "GIL"을 사용하기 때문에 파이썬이 별도의 스레드를 동시에 실행할 수 있습니까?


정보 :

이것을 읽은 후 파이썬이 멀티 코어 프로세서를 활용할 수 있는지 여부에 대해 다소 불확실했습니다. 파이썬이 잘했듯이, 그렇게 강력한 능력이 부족할 것이라고 생각하는 것은 정말 이상합니다. 그래서 불확실한 느낌이 들어 여기서 물어보기로했습니다. 다중 스레드 프로그램을 작성하면 다중 코어에서 동시에 실행할 수 있습니까?


대답은 "예,하지만 ..."입니다.

그러나 동시성을 위해 일반 스레드를 사용할 때는 cPython이 불가능합니다.

당신도 같은 것을 사용할 수 있습니다 multiprocessing, celery또는 mpi4py다른 프로세스로 병렬 작업을 분할;

또는 Jython 또는 IronPython 과 같은 것을 사용하여 GIL이없는 대체 인터프리터를 사용할 수 있습니다.

더 부드러운 솔루션은 무거운 CPU 작업을 위해 GIL을 위반하지 않는 라이브러리를 사용하는 것입니다. 예를 들어 numpyGIL을 유지하지 않고 무거운 작업을 수행 할 수 있으므로 다른 파이썬 스레드가 진행될 수 있습니다. ctypes이러한 방식으로 라이브러리를 사용할 수도 있습니다 .

CPU 바운드 작업을 수행하지 않는 경우 Python이 IO를 기다리는 동안 GIL을 획득하지 않기 때문에 GIL 문제를 완전히 무시할 수 있습니다.


파이썬 스레드 는 많은 코어를 이용할 수 없습니다. 이것은 거의 확실하게 사용하는 파이썬 (cPython)의 C 구현에서 GIL (전역 인터프리터 잠금)이라는 내부 구현 세부 사항 때문입니다.

해결 방법은 이러한 목적으로 개발 된 http://www.python.org/dev/peps/pep-0371/multiprocessing 모듈 입니다.

문서 : http://docs.python.org/library/multiprocessing.html

(또는 병렬 언어를 사용하십시오.)


CPython (Python의 고전적이고 널리 사용되는 구현)은 동시에 Python 바이트 코드를 실행하는 스레드를 두 개 이상 가질 수 없습니다. 즉, 컴퓨팅 바운드 프로그램은 하나의 코어 만 사용합니다. C 확장 (예 : numpy) 내에서 발생하는 I / O 작업 및 컴퓨팅은 동시에 작동 할 수 있습니다.

Python의 다른 구현 (예 : Jython 또는 PyPy)은 다르게 작동 할 수 있지만 세부 사항은 명확하지 않습니다.

일반적인 권장 사항은 많은 스레드보다는 많은 프로세스를 사용하는 것입니다.


스레드는 프로세스를 공유하고 프로세스는 코어에서 실행되지만 Python의 다중 처리 모듈을 사용하여 별도의 프로세스에서 함수를 호출하고 다른 코어를 사용할 수 있습니다. 또는 하위 프로세스 모듈을 사용하여 코드 및 비 Python 코드도 실행할 수 있습니다. .


내 우분투 14.04, python 2.7 64 비트에서 4 개의 코어를 모두 사용하는 예제 코드.

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

스크립트를 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

저에게는 병렬 실행이 더 빨랐습니다.


나에게도 똑같다. 병렬이 더 빨랐습니다.

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

순차 프로세스 동안 CPU는 사용률의 25 %가되고 병렬 프로세스 동안 CPU는 100 %가됩니다.

참조 URL : https://stackoverflow.com/questions/7542957/is-python-capable-of-running-on-multiple-cores

반응형