programing

Python은 멀티스레딩을 지원합니까?실행 시간을 단축할 수 있습니까?

minimums 2023. 7. 27. 21:46
반응형

Python은 멀티스레딩을 지원합니까?실행 시간을 단축할 수 있습니까?

저는 멀티스레딩이 파이썬에서 작동하는지에 대해 약간 혼란스럽습니다.

저는 이것에 대해 많은 질문들이 있었다는 것을 알고 있고 그것들을 많이 읽었지만, 저는 여전히 혼란스럽습니다.저는 제 경험을 통해 다른 사람들이 여기 StackOverflow에 멀티스레딩이 실제로 Python에서 가능하다는 것을 알고 있습니다.그렇다면 왜 모두가 파이썬은 GIL에 의해 잠겨 있고 한 번에 하나의 스레드만 실행할 수 있다고 말하는 것입니까?확실히 효과가 있습니다.아니면 제가 여기서 얻을 수 없는 어떤 차이점이 있나요?

또한 많은 포스터/응답자들은 스레드화가 여러 코어를 사용하지 않기 때문에 제한적이라고 계속 언급하고 있습니다.그러나 동시에 작업을 수행하여 결합된 워크로드를 더 빠르게 처리하기 때문에 여전히 유용하다고 생각합니다.내 말은, 그렇지 않으면 왜 파이썬 스레드 모듈이 존재할까요?

업데이트:

지금까지 답변해 주셔서 감사합니다.멀티스레딩은 일부 IO 작업에 대해서만 병렬로 실행되지만 CPU 바인딩된 여러 코어 작업에 대해서는 한 번에 하나만 실행할 수 있습니다.

저는 이것이 실제적인 측면에서 저에게 어떤 의미를 갖는지 완전히 확신할 수 없기 때문에, 제가 멀티 스레드화하고 싶은 작업의 예를 들어보겠습니다.예를 들어, 매우 긴 문자열 목록을 반복적으로 살펴보고 각 목록 항목에 대해 몇 가지 기본적인 문자열 작업을 수행하려고 합니다.목록을 분할하여 새 스레드에서 루프/문자열 코드로 처리할 각 하위 목록을 보내고 결과를 대기열로 다시 보내면 이러한 워크로드가 대략 동시에 실행됩니까?가장 중요한 것은 이론적으로 스크립트 실행 시간이 단축된다는 것입니까?

또 다른 예는 PIL을 사용하여 4개의 서로 다른 스레드에서 4개의 서로 다른 사진을 렌더링하고 저장할 수 있으며, 이 작업이 하나씩 차례로 사진을 처리하는 것보다 빠를 수 있습니까?이 속도 구성 요소가 정확한 용어가 무엇인지 보다는 제가 정말로 궁금해하는 부분인 것 같습니다.

멀티프로세싱 모듈에 대해서도 알고 있지만, 현재 저의 주된 관심사는 소규모에서 중간 규모의 작업 부하(10-30초)입니다. 따라서 하위 프로세스의 시작이 느릴 수 있기 때문에 멀티스레딩이 더 적합할 것이라고 생각합니다.

GIL은 스레드화를 방지하지 않습니다.GIL은 한 번에 하나의 스레드만 Python 코드를 실행하도록 하고 제어는 여전히 스레드 간에 전환됩니다.

그러면 GIL이 방지하는 것은 스레드를 병렬로 실행하기 위해 둘 이상의 CPU 코어 또는 별도의 CPU를 사용하는 것입니다.

이는 Python 코드에만 적용됩니다.C 확장은 GIL을 릴리스하여 C 코드의 여러 스레드와 하나의 파이썬 스레드를 여러 코어에서 실행할 수 있습니다.되는 I됩니다.select()소켓 읽기 및 쓰기를 요구하므로 Python은 멀티 스레드 멀티 코어 설정에서 네트워크 이벤트를 합리적으로 효율적으로 처리할 수 있습니다.

그러면 많은 서버 배포가 두 개 이상의 Python 프로세스를 실행하여 OS가 프로세스 간의 스케줄링을 처리하여 CPU 코어를 최대한 활용할 수 있도록 합니다.사용 사례에 적합한 경우 라이브러리를 사용하여 하나의 코드베이스 및 상위 프로세스에서 여러 프로세스에 걸쳐 병렬 처리를 처리할 수도 있습니다.

GIL은 CPython 구현에만 적용됩니다. Jython과 IronPython은 다른 스레드 구현(네이티브 Java VM 및 )을 사용합니다.각각 NET 공통 런타임 스레드).

업데이트 주소를 직접 지정하는 방법순수 Python 코드를 사용하여 병렬 실행에서 속도 향상을 시도하는 모든 작업은 스레드 Python 코드가 한 번에 실행되는 하나의 스레드에 잠겨 있기 때문에 속도 향상을 보지 못합니다.그러나 C 확장자와 I/O를 함께 사용하는 경우(예: PIL 또는 numpy 작업) 및 모든 C 코드가 하나의 활성 Python 스레드와 병렬로 실행될 수 있습니다.

Python 스레드는 응답성이 높은 GUI를 생성하거나 I/O가 Python 코드보다 병목 현상이 심한 여러 짧은 웹 요청을 처리하는 데 유용합니다.계산 집약적인 파이썬 코드를 병렬화하는 데 적합하지 않습니다.multiprocessing이러한 작업을 위한 모듈 또는 전용 외부 라이브러리에 위임합니다.

네. :)

로우 레벨 스레드 모듈과 하이 레벨 스레드 모듈이 있습니다.하지만 단순히 멀티코어 기계를 사용하고 싶다면 멀티프로세싱 모듈이 최선의 방법입니다.

문서에서 인용한 내용:

CPython에서는 Global Interpreter Lock으로 인해 특정 성능 지향 라이브러리가 이러한 제한을 극복할 수 있더라도 한 번에 하나의 스레드만 Python 코드를 실행할 수 있습니다.응용 프로그램에서 멀티 코어 시스템의 계산 리소스를 더 잘 사용하려면 멀티 프로세싱을 사용하는 것이 좋습니다.그러나 여러 I/O 바인딩된 태스크를 동시에 실행하려는 경우에도 스레드는 여전히 적합한 모델입니다.

스레드화 허용 파이썬에서 유일한 문제는 GIL이 한 번에 하나의 스레드만 실행되도록 하는 것입니다(병렬화 없음).

따라서 기본적으로 계산 속도를 높이기 위해 코드를 멀티스레드화하려는 경우 한 번에 하나의 스레드만 실행되므로 속도가 빨라지지 않습니다. 예를 들어 데이터베이스와 상호 작용하는 데 사용하면 속도가 빨라집니다.

저는 포스터를 동정합니다. 왜냐하면 답은 변함없이 "당신이 무엇을 하고 싶은지에 달려 있습니다."이기 때문입니다.하지만 파이썬에서의 병렬 속도 향상은 멀티프로세싱에서도 경험상 항상 끔찍했습니다.

예를 들어 이 튜토리얼을 확인하십시오(구글에서 두 번째로 높은 결과). https://www.machinelearningplus.com/python/parallel-processing-python/

나는 이 코드에 타이밍을 두고 풀 맵 기능의 프로세스 수(2,4,8,16)를 늘렸고 다음과 같은 나쁜 타이밍을 얻었습니다.

serial 70.8921644706279 
parallel 93.49704207479954 tasks 2
parallel 56.02441442012787 tasks 4
parallel 51.026168536394835 tasks 8
parallel 39.18044807203114 tasks 16

코드: # 시작할 때 어레이 크기 증가 # 내 컴퓨팅 노드에는 40개의 CPU가 있으므로 여기에 여유가 많습니다.

arr = np.random.randint(0, 10, size=[2000000, 600])
.... more code ....
tasks = [2,4,8,16]

for task in tasks:
    tic = time.perf_counter()
    pool = mp.Pool(task)

    results = pool.map(howmany_within_range_rowonly, [row for row in data])

    pool.close()
    toc = time.perf_counter()
    time1 = toc - tic
    print(f"parallel {time1} tasks {task}")

언급URL : https://stackoverflow.com/questions/20939299/does-python-support-multithreading-can-it-speed-up-execution-time

반응형