병렬 컴퓨팅, 멀티 프로세싱,

2007년은 제가 대학원에 입학한 해였고 컴퓨터를 이용한 계산에 대한 진지한 연구를 시작한 해였습니다.

그리고 멀티 코어 CPU가 대중화되기 시작한 시기이기도 합니다.

뭐, 이전에는 서버에 CPU가 2개 장착되어 있었다거나, 여러 대의 서버를 연결하여 클러스터를 형성했거나…

이 무렵 개인용 컴퓨터(PC)에도 병렬 컴퓨팅을 활용하기 위해 다중 코어가 장착되었습니다.

여하튼 연구 초기부터 병렬 컴퓨팅은 내가 (컴퓨팅 자원이 필요할 때) 사용해야 하는 기술이었다.

멀티코어 CPU와 함께 하나의 코어를 마치 두 개의 코어처럼 논리적으로 처리하려는 하이퍼스레딩(Intel)이 나왔지만 실제 성능 향상이 거의 없어 사용하지 않았다.

AMD는 또한 동시 멀티스레딩을 지원합니다(동시 멀티스레딩SMT)가 지원됩니다.

병렬 컴퓨팅, 분산 컴퓨팅, 다중 처리 등은 모두 비슷한 의미를 갖지만 사용 가능한 환경과 방법이 광범위하기 때문에 병렬 컴퓨팅의 의미는 약간 다릅니다.

여러 대의 컴퓨터가 있는 경우, 하나에 여러 개의 프로세서가 있는 경우, 메모리를 공유하는 경우, 공유하지 않는 경우 등.

분산 컴퓨팅은 일반적으로 여러 대의 컴퓨터를 의미합니다.

병렬 컴퓨팅에 대해 이야기하려면 프로세서와 프로세스 간의 관계에 대해 이야기해야 합니다.

프로세서는 컴퓨팅 장치를 의미하고 프로세스는 소프트웨어를 의미합니다.

CPU였던 프로세서는 이제 코어 또는 스레드입니다.

1 CPU 8 코어 16 스레드, 16 프로세서로 생각할 수 있습니다.

프로세스를 처리 단위로 생각할 수 있으며 프로세스는 일반적으로 실행 파일을 실행할 때 프로그램을 실행합니다.

이것은 프로세스입니다.

물론 동시에 여러 프로세스를 실행하거나 하나의(상위) 프로세스가 여러 하위 프로세스를 생성하도록 하는 것도 가능합니다.

병렬 컴퓨팅은 훌륭하게 들리지만 때로는 원칙이 간단합니다.

예를 들어 파라미터만 바꿔서 100번의 시뮬레이션을 해서 결과를 보고 싶다면?

약 10대의 컴퓨터가 있다고 가정해 보겠습니다.

서로 다른 시뮬레이션이 서로 독립적으로 실행될 수 있습니다.

동시에 100가지 일을 하면 됩니다.

그런 다음 100개의 작업을 10개로 분할하고 각 컴퓨터에서 10개를 실행할 수 있습니다.

컴퓨터에 많은 프로세스와 메모리가 있는 경우 10개를 동시에 실행하거나 차례로 실행하여 한 프로세스가 완료되면 다른 프로세스가 시작되도록 합니다.

조금 화가 났던 기억이 나네요… 당시 연구실에 들어가면서 처음으로 Core 2 Quad…4 Multi-Core CPU를 사용할 수 있는 상황에서 연구실 컴퓨터를 바꾸기로 했습니다.

그래서 새 컴퓨터 3대를 사서 부지런히 세팅을 해봤는데.. 선배님들께서 직접 사용해보니 4배 빨라야 하는데 1.5배(시계차이 개선)만 빠릅니다.

…아… 정말.. 대학원 생활이 힘들다.

물론 코드를 병렬로 작성하지 않기 때문입니다.

사실 이 경우 병렬 코드가 없더라도 이전에 1개 실행하던 프로그램 4개를 동시에 1대의 컴퓨터에서 간단하게 실행할 수 있기 때문에 병렬화 코드가 없어도 금전적 이점이 매우 큽니다.

100만원짜리 컴퓨터에서 1개가 아닌 4개를 동시에 실행할 수 있다는 것은 컴퓨터를 12대가 아닌 3대만 살 수 있다는 뜻이다.

많은 메모리를 필요로 하는 작업에는 이 작업을 수행할 수 없지만…

내가 이것을 말하는 이유는 많은 프로그램을 실행해야 하는 경우 하나의 프로그램에 병렬화 루틴을 작성하여 여러 프로세서를 삽입하는 대신 그러한 프로그램을 동시에 여러 개 실행할 수 있기 때문입니다.

사람마다 상황이 다르고 적절한 병렬화 방법도 매우 다릅니다.

그러나 병렬 컴퓨팅을 크게 두 가지 범주로 나누면

하나의 프로세스만 실행되고 여러 프로세서가 메모리를 공유하는 방법(일반적으로 openmp, multithreaded, CUDA)

이렇게 하면 여러 프로세스가 실행되고 프로세스당 메모리를 공유하지 않습니다.

(일반적인 MPI, 다중 프로세스)

물론 특히 여러 대의 컴퓨터가 있는 경우 컴퓨터 간에 메모리를 공유할 수 없으므로 후자를 사용해야 합니다.

조금 더 나아가 여러 프로세스가 있을 수 있으며 각 프로세스에는 여러 프로세서가 있을 수 있습니다.

프로세스 측면에서 생각해보면 메모리는 같은 프로세스에 속한 프로세서 간에 공유되며 프로세스 간에는 메모리를 공유할 수 없습니다.

정보를 전달해야 하는 경우 대신 프로세스 간에 전달됩니다.

MPI는 서로 다른 프로세스 간의 통신 프로토콜인 메시지 전달 인터페이스입니다.

내가 사용한 첫 번째 병렬 프로그래밍은 MPI였는데 약간 까다롭습니다.

개념적으로 이해해야 할 것도 있고 기술적으로 처리해야 할 것도 많다.

특히 컴퓨터 간의 통신이 필요한 경우 컴퓨터 설정이 어렵습니다.

MPI는 동시에 여러 프로세스를 실행하며 각 프로세스에는 일반적으로 하나의 프로세서가 있습니다.

예제에 설명된 여러 독립 프로그램을 실행하는 경우 서로 통신할 필요조차 없기 때문에 MPI와 같은 것을 사용할 필요가 없습니다.

MPI는 빈번한 통신이 필요할 때 사용하는 방법입니다.

예를 들어 연산을 여러 프로세스로 나누어 각 프로세스에 분산시키면 각 프로세스는 자신의 연산을 수행하고 그 결과를 하나로 모아 각 프로세스에 분산시켜 연산을 다시 수행한다.

또는 서로 다른 프로세스 간에 필요한 정보를 통신을 통해 작업 중에 도입할 수도 있습니다.

더 힘들어 보인다…

통신이란 다른 프로세스에 배포하기 위해 메모리 내용을 복사하고 전달하는 것을 의미합니다.

다른 프로세스는 프로세스의 메모리에 저장된 내용을 볼 수 없기 때문입니다.

mpi와 같은 공유 세계에서 동시에 여러 프로그램을 실행할 수 있지만 경우에 따라 부모 프로세스가 먼저 실행되고 자식 프로세스가 생성됩니다.

(MPI는 어떻게 보면 그런 것 같지만… 모든 아이들에게는 부모가 있다.

)

반면에 openmp는 정말 사용하기 쉬운 공유 메모리 병렬 프로그래밍 기술입니다.

C나 Fortran에서 사용이 가능하지만 for 문 거의 바로 앞에 한 줄만 추가하면 사용이 가능하다.

프로세스에 속한 프로세서는 메모리를 공유하므로 통신이 필요하지 않습니다.

대신 프로세스 간에 메모리를 공유하기 때문에 서로 간섭할 수 있으므로 주의해야 합니다.

누군가는 고기를 잘라야 하고 누군가는 고기를 튀겨야 하는데, 자르지 않은 고기를 튀기거나, 얇게 썬 고기를 가져다가 튀기거나, 튀긴 고기를 자를 수는 없다.

다중 프로세스 병렬 프로그램을 실행한 후 top과 같은 명령을 실행하면 여러 프로그램(프로세스)이 실행되고 각각 최대 CPU 사용률이 약 100%인 것을 확인할 수 있습니다.

반면에 다중 스레드 병렬 프로그램에서는 하나의 프로그램(프로세스)만 실행되고 해당 프로세스가 CPU의 수백 퍼센트를 차지하는 것을 볼 수 있습니다.

BTW … 문제는 Python입니다.

Python은 또한 멀티스레딩과 멀티프로세싱을 지원하지만 멀티프로세싱은 어쨌든 실행 중인 여러 프로세스가 있기 때문에 문제가 되지 않습니다.

문제는 Python 멀티스레딩입니다.

파이썬은 컴파일러가 아니라 인터프리터입니다.

즉, 코드가 계속해서 해석되고 실행됩니다.

그러나 멀티스레딩을 사용하는 경우 한 번에 하나의 인터프리터만 사용할 수 있습니다.

소위 전역 인터프리터 잠금(GIL)이 있습니다.

파이썬 멀티스레딩은 하나의 프로세스에 여러 프로세서가 참여하는 방식인데 문제는 프로세스당 하나의 인터프리터만 있기 때문에 여러 프로세서가 동시에 인터프리터를 사용할 수 없다는 점이다.

누군가 사용하면 다른 사람이 사용할 수 없도록 잠깁니다.

파이썬의 특성상 인터프리터가 계속 작동하면서 프로그램이 실행되는데 이 병목 현상이 미치는 영향이 크기 때문에 병렬화 효율이 매우 낮다.

그래도 특정 경우에 사용할 수 있는 것 같지만… 문제는 인터프리터가 큰 병목 현상이 아니라는 것입니다… 아니면 다른 언어에서 병렬로 컴파일된 루틴을 실행하는 것입니까? … 잘 모르겠습니다.

솔직히 말해서 그들이 왜 그랬는지 모르겠습니다.

기술적으로 해결하기 어렵기 때문일까요…?

그래도 해결하려고 노력하는 것 같긴 한데…

메모리 공유 형태의 멀티스레딩이 Python에서 제대로 작동하지 않는다는 점을 고려하면 현재는 이렇게 하지 않는 것이 좋습니다.