멀티코어 프로세싱은 장점과 단점을 동시에 가지고 있으며, 최상의 성능을 끌어내기 위해서는 프로그램에 CPU 코어를 수동으로 할당해야 하는 경우가 있습니다. 이를 'CPU 어피니티(CPU Affinity)'라고 부릅니다. Linux에서 이 작업의 핵심 도구는 바로 taskset입니다. 다소 생소하고 어렵게 느껴질 수 있지만, 이 글에서는 쉬운 단계별로 과정을 정리해 드리겠습니다.
taskset 기본 사용법
taskset의 활용은 크게 두 가지로 나눌 수 있습니다. 하나는 새로 실행할 프로그램에 CPU 어피니티를 지정하는 것이고, 다른 하나는 이미 실행 중인 프로그램의 어피니티를 변경하는 것입니다. 새 프로그램을 실행하는 방법이 더 간단하므로 여기서부터 시작하겠습니다. 기본 실행 명령 형식은 다음과 같습니다:
taskset -c cpu-core-number(s) application
CPU 코어 번호를 입력하기 전에 한 가지 주의할 점이 있습니다. Unix 계열 시스템의 번호 매기기는 일반적으로 0부터 시작합니다. 즉, 첫 번째 코어는 0, 두 번째 코어는 1이 됩니다. 따라서 듀얼코어 시스템은 코어 0과 1을 가지며, 쿼드코어 시스템은 코어 0, 1, 2, 3을 가집니다.
예를 들어, 듀얼코어 시스템에서 Audacity를 실행하면서 두 번째 코어에서만 동작하게 하고 싶다면 다음과 같이 입력합니다:
taskset -c 1 audacity
여러 개의 코어에 할당하기
실제 사례를 하나 소개하자면, 어떤 시스템에서 Chrome이 영상 스트리밍 중 프레임이 끊기는 문제가 있었지만, 두 개의 코어에 할당한 후에는 안정적으로 동작했습니다. 쿼드코어 시스템에서 Chrome을 세 번째와 네 번째 코어에 할당하려면 다음 명령을 사용합니다:
taskset -c 2,3 google-chrome
CPU 어피니티는 반드시 연속된 코어에 할당할 필요가 없습니다. 원하는 코어를 자유롭게 조합할 수 있습니다. 예를 들어 6코어 시스템에서 Chrome을 두 번째와 여섯 번째 코어에서 구동하고 싶다면 다음과 같이 입력합니다:
taskset -c 1,5 google-chrome
또한 하이픈(-)을 사용하면 애플리케이션을 여러 코어 범위에 걸쳐 분산시킬 수 있습니다. 많은 구형 프로그램이나 시스템 프로세스는 기본적으로 첫 번째 코어에서 실행되는 경향이 있는데, 만약 첫 번째 코어를 최대한 여유롭게 유지하면서 대형 애플리케이션을 나머지 모든 코어에 분산시키고 싶다면 어떻게 해야 할까요?
예를 들어 8코어 시스템에서 Steam을 두 번째 코어부터 여덟 번째 코어까지 사용하며 실행하려면 다음 명령을 입력합니다:
taskset -c 1-7 steam
이미 실행 중인 프로그램의 어피니티 변경하기
taskset은 애플리케이션을 새로 실행할 때만 사용할 수 있는 것이 아닙니다. 이미 실행 중인 프로그램의 CPU 어피니티도 변경할 수 있습니다. 다만, 어피니티를 변경하기 전에 먼저 해당 프로세스의 PID(Process ID)를 알아야 합니다.
애플리케이션의 PID를 확인하는 방법은 여러 가지가 있습니다. 데스크톱 환경의 시스템 모니터를 사용해도 되지만, 가장 빠르고 확실한 방법은 top 명령을 사용하는 것입니다:
top
화면 오른쪽에는 실행 중인 모든 프로세스의 이름이 표시되고, 왼쪽에는 그에 해당하는 프로세스 ID가 나타납니다.
PID를 확인했다면 메모해 두세요. 이후 단계에서 바로 사용하게 됩니다. 이번 예제에서는 6코어 구형 PC에서 고해상도 Matroska(MKV) 영상을 재생 중인 VLC를 사용해 보겠습니다. VLC에서 최상의 성능을 끌어내기 위해 다양한 CPU 어피니티 조합을 실험해 보겠습니다.
이미 실행 중인 프로세스의 어피니티를 변경하는 명령 형식은 다음과 같습니다:
taskset -cp core-numbers PID
위 스크린샷에서 VLC의 PID는 20485입니다. VLC를 네 번째, 다섯 번째, 여섯 번째 코어에서 실행해 보겠습니다. Unix 넘버링 기준으로는 3~5번이므로, 최종 명령은 다음과 같습니다:
taskset -cp 3-5 20485
그렇다면 변경하기 전에 현재 설정된 어피니티를 먼저 확인하고 싶다면 어떻게 해야 할까요? 이 경우 코어 번호를 입력하지 않으면 taskset이 현재 어피니티 상태를 알려줍니다. 마지막 명령에서 코어 번호를 제거하면:
taskset -cp 20485
VLC가 현재 모든 코어에 분산되어 있다는 결과를 확인할 수 있습니다.
이번에는 다른 프로그램으로 다시 실습해 보겠습니다. SMPlayer로 대용량 Matroska 파일을 재생 중이고, SMPlayer는 이미 실행된 상태라고 가정합니다. top으로 확인한 결과 PID는 16058입니다.
먼저 현재 설정된 어피니티를 확인해 보겠습니다. -cp 옵션만 사용하고 코어 번호 없이 명령을 실행하면, 현재 모든 코어에 분산되어 있는 것을 확인할 수 있습니다.
이제 앞서 VLC 실험과 동일하게 SMPlayer를 세 개의 코어에 배분해 보겠습니다. 명령은 다음과 같습니다:
taskset -cp 3-5 16058
생각보다 간단하지 않나요? 참고로 PC 성능을 직접 벤치마크해 보고 싶다면, CPU 스트레스 테스트에 유용한 8가지 도구를 소개한 가이드도 함께 확인해 보시기 바랍니다.