Linux에서 작업 세트를 사용하는 멀티 코어 시스템의 Python GIL(Global Interpreter Lock) 해결 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/990102

문제

그래서 저는 방금 Python GIL(Global Interpreter Lock)에 대한 이 강연을 시청했습니다. http://blip.tv/file/2232410.

요점은 GIL이 단일 코어 시스템에 매우 적합한 설계라는 것입니다(Python은 기본적으로 스레드 처리/스케줄링을 운영 체제에 맡깁니다).그러나 이는 멀티 코어 시스템에서 심각한 역효과를 낳을 수 있으며 CPU 집약적인 스레드에 의해 IO 집약적인 스레드가 심하게 차단되고 컨텍스트 전환 비용이 발생하며 ctrl-C 문제[*] 등이 발생하게 됩니다.

따라서 GIL은 기본적으로 하나의 CPU에서 Python 프로그램을 실행하도록 제한하므로 이것을 받아들이고 Linux에서 작업 세트를 사용하여 프로그램의 선호도를 시스템의 특정 코어/CPU로 설정하는 것이 어떻겠습니까(특히 다음과 같은 상황에서). 멀티 코어 시스템에서 실행되는 여러 Python 앱)?

그래서 궁극적으로 내 질문은 다음과 같습니다.Python 응용 프로그램과 함께 Linux에서 작업 세트를 사용해 본 사람이 있습니까(특히 Linux 시스템에서 여러 응용 프로그램을 실행하여 특정 코어에 바인딩된 하나 또는 두 개의 Python 응용 프로그램과 함께 여러 코어를 사용할 수 있는 경우) 그렇다면 결과는 무엇입니까?할 가치가 있나요?특정 워크로드의 경우 상황이 더 악화되나요?나는 이것을 하고 테스트할 계획이지만(기본적으로 프로그램을 실행하는 데 어느 정도 시간이 걸리는지 확인) 다른 사람들의 경험에 대해 듣고 싶습니다.

덧셈:David Beazley(링크된 비디오에서 강연하는 사람)는 일부 C/C++ 확장이 GIL 잠금을 수동으로 해제하고 이러한 확장이 멀티 코어에 최적화되어 있는지(예:과학 또는 수치 데이터 분석 등) 숫자 처리를 위해 멀티 코어의 이점을 얻는 대신 확장은 단일 코어로 제한된다는 점에서 사실상 무력화됩니다(따라서 프로그램 속도가 크게 느려질 수 있음).반면에 이와 같은 확장 기능을 사용하지 않는 경우

내가 멀티프로세싱 모듈을 사용하지 않는 이유는 (이 경우) 프로그램의 일부가 네트워크 I/O 바인딩(HTTP 요청)이 많기 때문에 작업자 스레드 풀을 갖는 것이 성능을 최대한 끌어내는 훌륭한 방법이기 때문입니다. 스레드가 HTTP 요청을 실행한 다음 I/O를 기다리고 있기 때문에 GIL을 포기하고 다른 스레드가 해당 작업을 수행할 수 있으므로 프로그램의 일부는 CPU를 크게 손상시키지 않고 쉽게 100개 이상의 스레드를 실행할 수 있으며 실제로 사용할 수 있습니다. 사용 가능한 네트워크 대역폭.스택리스 Python/etc에 대해서는 프로그램을 다시 작성하거나 Python 스택을 교체하는 데 지나치게 관심이 없습니다(가용성도 문제가 될 수 있음).

[*] 메인 스레드만 신호를 받을 수 있으므로 Ctrl-C를 보내면 Python 인터프리터는 기본적으로 메인 스레드를 실행하여 신호를 처리할 수 있도록 시도하지만 어떤 스레드가 실행되는지 직접 제어하지 않기 때문에 ( 이는 운영 체제에 맡겨집니다. 기본적으로 OS는 결국 메인 스레드에 도달할 때까지 스레드를 계속 전환하도록 지시합니다(운이 좋지 않으면 시간이 걸릴 수 있음).

도움이 되었습니까?

해결책

Python의 성능 향상을 위해 작업 세트를 사용하는 사람에 대해 들어본 적이 없습니다.귀하의 경우에 그런 일이 일어날 수 없다는 뜻은 아니지만, 다른 사람들이 귀하의 벤치마킹 방법을 비판하고 검증할 수 있도록 결과를 게시하십시오.

하지만 개인적으로는 메시지 큐를 사용하여 CPU 바인딩 스레드에서 I/O 스레드를 분리하겠습니다.이렇게 하면 프런트 엔드가 이제 완전히 네트워크 I/O 바인딩(일부는 HTTP 인터페이스, 일부는 메시지 대기열 인터페이스 포함)되어 스레딩 상황에 이상적입니다.그런 다음 CPU 집약적인 프로세스는 다중 처리를 사용하거나 작업이 메시지 큐에 도착할 때까지 기다리는 개별 프로세스일 수 있습니다.

장기적으로는 스레드 I/O 프런트 엔드를 Twisted 또는 다음과 같은 것으로 교체하는 것을 고려할 수도 있습니다. 이벤트렛 성능에 도움이 되지 않더라도 확장성을 향상시켜야 하기 때문입니다.필요에 따라 원하는 수의 머신+CPU를 통해 메시지 대기열을 실행할 수 있으므로 백엔드는 이제 이미 확장 가능합니다.

다른 팁

또 다른 해결책은 다음과 같습니다.http://docs.python.org/library/multiprocessing.html

참고 1:이것은 ~ 아니다 Python 언어의 한계이지만 CPython 구현의 한계입니다.

노트 2:선호도와 관련하여 OS 자체에는 문제가 없어야 합니다.

흥미로운 해결책은 Ryan Kelly가 자신의 블로그에 보고한 실험입니다. http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2/

결과는 매우 만족스러운 것 같습니다.

나는 수년에 걸쳐 다음과 같은 경험 법칙이 충분하다는 것을 알았습니다.작업자가 일부 공유 상태에 의존하는 경우 코어당 하나의 다중 처리 프로세스(CPU 바인딩)를 사용하고 코어당 작업자 스레드의 수정 풀(I/O 바인딩)을 사용합니다.OS는 다양한 Python 프로세스를 코어에 할당하는 작업을 담당합니다.

Python GIL은 Python 인터프리터별로 제공됩니다.즉, 다중 처리를 수행하는 동안 문제를 피하는 유일한 방법은 단순히 여러 인터프리터를 시작하는 것입니다(예:동시성을 위해 스레드 대신 별도의 프로세스를 사용하고 프로세스(예: 소켓) 간의 통신을 위해 다른 IPC 기본 요소를 사용합니다.즉, I/O 호출을 차단하는 스레드를 사용할 때 GIL은 문제가 되지 않습니다.

앞서 언급한 GIL의 주요 문제점은 2개의 서로 다른 Python 코드 스레드를 동시에 실행할 수 없다는 것입니다.차단 I/O 호출에 대한 스레드 차단은 차단되므로 Python 코드가 실행되지 않습니다.이는 GIL을 차단하지 않음을 의미합니다.별도의 Python 스레드에 두 개의 CPU 집약적인 작업이 있는 경우 GIL은 Python에서 다중 처리를 종료합니다(앞에서 지적한 대로 CPython 구현만 해당).GIL은 CPU #1이 Python 스레드를 실행하는 것을 중지하는 반면 CPU #0은 다른 Python 스레드를 실행하는 중이기 때문입니다.

GIL이 Python에서 제거될 때까지 스레드 대신 코루틴을 사용할 수 있습니다.나는 이 전략이 적어도 한 사례에서 greenlet을 사용하여 두 개의 성공적인 스타트업에 의해 구현되었다는 좋은 권위를 가지고 있습니다.

이것은 꽤 오래된 질문이지만 Python 및 멀티 코어 시스템의 성능과 관련된 정보를 검색할 때마다 이 게시물이 항상 결과 목록에 있으므로 이 내용을 내 앞에 두지 않고 내 생각을 공유하지 않습니다.

각 작업에 대한 스레드를 생성하는 대신 코드를 해석하는 cpython 컴파일러의 또 다른 프로세스를 생성하는 다중 처리 모듈을 사용할 수 있습니다.이는 귀하의 애플리케이션이 멀티코어 시스템을 활용하도록 만들 것입니다.이 접근 방식에서 볼 수 있는 유일한 문제는 메모리에 완전히 새로운 프로세스 스택을 생성하면 상당한 오버헤드가 발생한다는 것입니다.(http://en.wikipedia.org/wiki/Thread_(컴퓨팅)#How_threads_differ_from_processes)

Python 다중 처리 모듈:http://docs.python.org/dev/library/multiprocessing.html

"멀티프로세싱 모듈을 사용하지 않는 이유는 (이 경우) 프로그램의 일부가 네트워크 I/O 바인딩(HTTP 요청)이 많기 때문에 작업자 스레드 풀을 갖는 것이 성능을 최대한 끌어내는 훌륭한 방법이기 때문입니다. ..."

이에 대해 프로세스 풀도 가질 수 있다고 생각합니다. http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers

ATT, 레오

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top