[python] 프로세스, 스레드와 CPU 코어 간 관계!

About_work·2024년 2월 14일
0

process, thread

목록 보기
15/23

질문 1. 1 process가 병렬적으로 여러 CPU core을 사용할 수 있나요? -> 있다.

  • 방법 1: 하나의 프로세스 내에서 여러 스레드를 생성하여 작업을 수행할 경우, 운영 체제의 스케줄러가여러 스레드를 다른 CPU 코어에 할당하여 병렬적으로 작업을 수행할 수 있습니다.
    • 그러나 Python의 표준 구현인 CPython에서는 Global Interpreter Lock (GIL)로 인해, 동시에 실행되는 스레드가 CPU 바운드 작업을 수행할 때 하나의 코어에서 순차적으로 실행되는 것처럼 보일 수 있음
    • 이 제한은 CPU 바운드 작업에 해당되며, I/O 바운드 작업에서는 여러 스레드가 효율적으로 병렬 처리될 수 있습니다.
  • 방법 2: 또한, GIL을 우회하는 C 확장 라이브러리를 사용하면 여러 CPU 코어를 효과적으로 활용할 수 있습니다.
    • 예: numpy
    • 얘는 진정한 의미의 병렬성 실현 가능

질문 2. 파이썬에서 ,하나의 프로세스(하나의 스레드만을 가지는)가, 여러 CPU 코어를 병렬적으로 사용하는 경우도 있니? -> 있다.

  • GIL을 우회하는 C 확장 라이브러리`를 사용하면 여러 CPU 코어를 효과적으로 활용할 수 있습니다.

질문 3. 파이썬에서 ,하나의 프로세스가, 특정 외부 라이브러리(예: NumPy, SciPy 등이 내부적으로 멀티스레딩을 사용할 수 있음)를 사용하면, 여러 CPU core을 사용할 수 있는 이유? -> 멀티 쓰레딩

  • 특정 외부 라이브러리(예: NumPy, SciPy)가 자체적으로 여러 스레드를 생성하여 멀티코어 CPU의 병렬 처리 능력을 활용
  • 예를 들어, NumPy와 SciPy는 과학 계산을 위해 내부적으로 최적화된 C/C++ 라이브러리(예: BLAS, LAPACK)를 사용
  • 이러한 라이브러리들은 CPU의 병렬 처리 능력을 활용할 수 있도록 설계되어 있어, 복잡한 계산을 수행할 때 여러 CPU 코어에서 동시에 연산을 수행할 수 있음

질문 4. 파이썬에서 ,하나의 프로세스가, 특정 외부 라이브러리(예: NumPy, SciPy 등을 통한 멀티 스레딩을 사용할 때, GIL을 회피하여 병렬 처리가 가능하니? -> 가능

  • 일반 파이썬:
    • Python의 GIL은 CPython 인터프리터에서 한 번에 하나의 스레드만이 Python 객체를 조작할 수 있도록 제한
    • GIL은 동시성(concurrency)는 허용하지만, 순수한 Python 코드에서의 병렬 처리(parallelism)는 제한합니다.
  • 병렬 처리의 가능성:
    • 그러나 NumPy, SciPy와 같은 특정 외부 라이브러리는 Python의 GIL 영향을 받지 않는 방식으로 설계되어 있음
    • 이 라이브러리들은 Python 외부에서, 예를 들어 C나 C++로 작성된 코드를 사용하여 병렬 처리를 수행
    • 이러한 코드는 GIL의 제한을 받지 않기 때문에, 하나의 프로세스 내에서도 멀티스레딩을 통해 진정한 병렬 처리를 실현할 수 있음
    • 즉, 이 라이브러리들은 GIL이 적용되는 Python 코드의 영역 밖에서 병렬 연산을 수행하므로, 여러 CPU 코어를 효과적으로 활용할 수 있음

질문 5. Numpy가 멀티 스레딩을 생성하는 기준이 있는지? 사용가능한 스레드 수(코어 수)를 제한할 수 있는지?

5. 1. NumPy가 스레드(즉, CPU 코어)를 사용하는 로직

  • NumPy는 내부적으로 BLAS (Basic Linear Algebra Subprograms) 및 LAPACK (Linear Algebra PACKage) 같은 저수준 라이브러리를 사용
  • 이러한 라이브러리들은 종종 멀티스레딩을 지원하여, 사용 가능한 CPU 코어를 활용해 병렬 연산을 수행합
  • NumPy가 사용할 스레드의 수는 다음과 같은 요소에 의해 결정될 수 있습니다:
  • 사용 중인 BLAS/LAPACK 라이브러리의 구현:
    • 예를 들어, OpenBLAS, MKL(Intel Math Kernel Library), ATLAS 등 라이브러리들은 일반적으로 시스템에서 사용 가능한 코어의 수를 자동으로 감지하고 최적의 스레드 수를 결정
  • 환경 변수 설정:
    • 사용자는 특정 환경 변수를 설정함으로써 사용할 스레드의 수를 조정할 수 있음
    • 예를 들어, MKL을 사용하는 경우 MKL_NUM_THREADS, OpenBLAS의 경우 OPENBLAS_NUM_THREADS 등을 설정할 수 있음

2. NumPy 모듈이 사용할 스레드(CPU 코어)의 수 제한

  • 네, 가능합니다. 사용하는 BLAS/LAPACK 라이브러리에 따라 환경 변수를 설정하여 스레드의 수를 제한할 수 있습니다. 예를 들어:

  • Intel MKL 사용 시: MKL이 제공하는 mkl_set_num_threads() 함수를 직접 호출하거나, 환경 변수 MKL_NUM_THREADS를 설정하여 스레드의 수를 제한할 수 있습니다.

    import os
    os.environ["MKL_NUM_THREADS"] = "4"  # MKL을 사용할 때 4개의 스레드 사용
  • OpenBLAS 사용 시: 환경 변수 OPENBLAS_NUM_THREADS를 설정합니다.

    import os
    os.environ["OPENBLAS_NUM_THREADS"] = "4"  # OpenBLAS를 사용할 때 4개의 스레드 사용
  • 환경 변수는 프로그램이 실행되기 전에 설정되어야 합니다. Python 스크립트 내에서 설정하는 경우, NumPy 또는 관련 라이브러리를 임포트하기 전에 설정하는 것이 좋습니다. 또한, 일부 시스템에서는 시스템 전체의 환경 변수를 설정하여 모든 애플리케이션에 대한 기본 스레드 수를 조정할 수도 있습니다.

  • 이러한 설정을 통해, NumPy 연산이 사용할 수 있는 스레드의 수를 제어하여, 자원 사용을 최적화하거나 다른 애플리케이션과의 자원 경쟁을 관리할 수 있습니다.

질문 6. 1개 프로세스 자체가 사용할 수 있는 코어의 수를 제한하는 방법? -> 가능함


질문 7. 1개의 프로세스가 실행되는 도중, 다른 CPU 코어로의 전환이 일어나나요?

  • 가능합니다. 운영 체제의 스케줄러는 다양한 요인을 고려하여 프로세스나 스레드를 다른 CPU 코어로 이동시킬 수 있음
  • 이는 시스템의 전반적인 성능과 효율성을 최적화하기 위한 조치로, 부하 분산, 에너지 효율성, 코어 간 온도 차이 등 다양한 요소가 고려될 수 있음
  • 따라서 하나의 프로세스가 실행되는 동안에도 운영 체제의 결정에 따라 사용하는 CPU 코어가 변경될 수 있음

질문 8. 하나의 프로세스가 현재 사용 중인 CPU 코어와 그 사용량 확인 방법

  • 파이썬 표준 라이브러리나 대부분의 외부 라이브러리는 특정 프로세스가 현재 사용 중인 CPU 코어의 번호를 직접적으로 확인할 방법을 제공하지 않습니다.
  • 이는 일반적으로 운영 체제의 스케줄러가 관리하는 정보이기 때문입니다.
  • 그러나 psutil 라이브러리를 사용하면 시스템의 전체 CPU 사용량 및 프로세스별 CPU 사용량을 확인할 수 있습니다.
  • 특정 프로세스가 사용하는 CPU 코어의 번호를 정확히 알아내는 것은 일반적인 사용 사례에서는 드물고,
  • 대부분의 응용 프로그램에서는 프로세스의 CPU 사용률이나 시스템 전체의 CPU 부하 분포에 더 관심을 가집니다.

질문 9: 아래 2개 비교하기

  1. 하나의 프로세스에서 numpy 모듈을 이용하여, 여러 CPU core을 사용하여 병렬적으로 연산 처리하기
  2. 연산을 여러 프로세스로 분산하여, 병렬적으로 연산 처리하기

질문 10: 하나의 프로세스 안에, 여러 쓰레드가 있으면 ,cpu core은 어떤 것을 사용할까? (numpy같은 외부 모듈 사용 안한다고 가정했을 때)

  1. 쓰레드와 CPU 코어 배당:
  • 파이썬에서 (실제로는 대부분의 프로그래밍 언어에서) 쓰레드에 CPU 코어를 고정적으로 "배당"하지 않습니다.
  • 운영 시스템의 스케줄러가 실행 가능한 쓰레드 풀에서 쓰레드를 선택하여 사용 가능한 CPU 코어에 할당합니다.
  • 이는 동적으로 이루어지며, 실행 중인 쓰레드는 시간이 지남에 따라 서로 다른 코어에 재할당될 수 있습니다.
  1. 쓰레드와 CPU 코어의 관계:
  • 한 시점에 CPU 코어 하나는 한 쓰레드의 명령어만을 실행할 수 있습니다.
  • 그러나 현대의 운영 시스템은 매우 빈번하게 쓰레드 간 전환을 수행하여 (컨텍스트 스위칭), 사용자에게 여러 프로세스와 쓰레드가 동시에 실행되는 것처럼 보이게 합니다.
  1. 쓰레드 수가 CPU 코어 수보다 많은 경우:
  • 이런 상황은 매우 흔하며, 실제로 대부분의 현대 컴퓨터 시스템에서는 쓰레드(또는 프로세스) 수가 CPU 코어 수를 초과
  • 이 경우, 운영 시스템의 스케줄러가 CPU 시간을 쓰레드 간에 분배하여, 모든 쓰레드가 실행될 수 있도록 관리합니다.
  • 이 과정에서 컨텍스트 스위칭이 발생하며, 쓰레드가 CPU 코어 사이를 이동할 수 있음
  1. 컨텍스트 스위칭의 오버헤드:
  • 쓰레드 수가 CPU 코어 수를 상당히 초과하면, 컨텍스트 스위칭으로 인한 오버헤드가 성능에 영향을 줄 수 있습니다.
  • 이 오버헤드는 CPU가 실제 유용한 작업을 수행하는 대신에 쓰레드 간 전환을 처리하는 데 시간을 소비하기 때문에 발생합니다.
  • 따라서, 효율적인 프로그래밍과 시스템 설계에서는 이러한 동작 원리를 고려하여, 애플리케이션의 성능을 최적화할 수 있는 쓰레드의 수와 작업 분배 방식을 결정해야 합니다.
  • 특히, 파이썬의 경우 GIL(Global Interpreter Lock)로 인해 멀티쓰레딩이 CPU 바운드 작업에서는 병렬 성능 향상을 기대하기 어려울 수 있으므로, 이러한 한계를 극복하기 위한 다른 접근 방식(예: 멀티 프로세싱)도 고려해볼 필요가 있습니다.

I/O 바운드 작업은 누가(어디에서) 수행한다고 보면 될까?

profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글