리눅스가 멀티 스레드를 지원하나요? 만약 내가 두개 이상의 프로세스를 실행 시킨다면, 모든 CPU들에 분산 처리가 될까요?
네, 프로세스와 커널-스레드들은 프로세서들에게 분산될것 입니다, 그러나 유저 스페이스 스레드들은 그렇지 않습니다.
어떤 아키텍처들에서 SMP를 지원 하나요?
SMP는 커널 2.0 이상 에서 인텔 MP1.1/1.4 를 지원하는 hypersparc(SS20 또는 그외), 인텔 486, 펜티엄 또는 그 이상에서 작동합니다. Richard Jelinek가 덧붙임: 4 개의 CPU 에서 테스트 되었고, MP 표준에 따르면 이론적으로 16 CPU 까지 지원할수 있습니다.
리눅스 커널 2.2.x 이상에서 UltraSparc, SparcServer, Alpha 와 PowerPC 등을 지원합니다.
MIPS, m68k 와 ARM 은 SMP를 지원하지 않습니다. m68k 와 ARM은 아마 영원히 지원하지 않을것입니다.
저는 MIPS-SMP 박스가 생기는 데로 SMP 지원을 위해 해킹을 해보려고 합니다.
리눅스 SMP 커널은 어떻게 만드나요?
많은 리눅스 배포본들이 SMP 커널 패키지를 포함하고 있지 않기 때문에 (역자주: 사실 요즘 배포본들은 대부분 포함하고 있지만,) 당신이 직접 만들어야 합니다. 만약 당신이 아직까지 커널 컴파일을 해본적이 없다면 이것은 좋은 이유가 될것입니다. 커널 컴파일에 대한 설명은 이 문서의 목적에 벗어나므로, 더 자세한 내용은 Linux Kernel Howto 를 참고하세요. (C. Polisher)
커널 2.0 이상 (2.1.132을 제외한) 에서는 커널의 주 Makefile (/usr/src/linux/Makefile)에서 SMP=1 라인의 주석을 풀어주면 됩니다.
커널 2.2.x 이상에서는 Processor type and features ---> [*] Symmetric multi-processing support "Symmetric multi-processing support"를 yes 로 해줍니다. (Michael Elizabeth Chastain).
그리고
Character devices ---> [*] Enhanced Real Time Clock Support
위와 같이 "RTC support" 를 yes 로 해줍니다. (Robert G. Brown). RTC 지원은 우리가 알고 있는 문제인 SMP 시스템의 시간의 느려짐을 해결하지는 않을것입니다, 그러나 부팅시 시간을 읽을때의 정지현상을 예방해 줍니다. 또한 RTC 기능은 몇몇 오리지날 인텔 메인보드에서 두번째 CPU를 인식하는데 필요합니다 (Richard Jelinek).
그리고
x86 커널에서는 APM (advanced power management) 기능을 넣지 마십시요! APM 과 SMP 는 호환하지 않습니다. 그리고 당신의 시스템은 분명히(최소한 아마도 ;)) 부팅시에 문제를 일으킬 것입니다 (Jakob Oestergaard). 2.1.x 이상의 SMP 커널에서는 APM 기능은 꺼집니다. 기본적으로 APM 은 SMP 시스템에서 미정이며, 무슨일이든지 일어날 수 있습니다. (Alan Cox)
그리고
x86 커널은 "MTRR (Memory Type Range Register)" 기능을 커널에 넣습니다. 이것은 몇몇 버그가 있는 BIOS에서 두번째 프로세서의 캐쉬 메모리가 작동하지 않는것을 해결 해 줍니다.
당신은 커널과 모든 관련 모듈들을 SMP 모드로 다시 컴파일 해야합니다. make modules 과 make modules_install 을 잊지 마십시요 (Alan Cox).
만약 모듈 적재 오류가 생긴다면 당신은 아마 모듈들을 컴파일 하지 않았거나 재 인스톨 하지 않았을 것입니다. 또한, 몇몇 2.2.x 대의 커널에서 SMP 커널에서 일반커널로의 재 컴파일시 문제가 있다는 보고가 있었습니다. 이것을 해결하려면 .config 파일을 저장해(다른 곳에) 놓은 다음, make mrproper 한후, 백업해놓은 .config 파일을 복사한후 커널을 재컴파일 합니다. (Wade Hampton). 커널 컴파일후 lilo 실행을 잊지 마십시요.
요약:
make config # 또는 menuconfig 또는 xconfig make dep make clean make bzImage # 또는 원하는 것으로(make zlilo,...) # 커널 이미지를 복사한후(/boot/에) lilo를 실행 make modules make modules_install |
비 SMP 커널을 어떻게 만드나요?
커널 2.0 대에서는 Makefile (/usr/src/linux/Makefile) 에서 SMP=1 라인을 주석 처리합니다.
2.2 대에서는 커널 설정시 "Symmetric multi-processing support" 에 no 로 대답하면 됩니다 (Michael Elizabeth Chastain).
당신은 커널과 관련 모듈 모두를 재 컴파일, 인스톨 해야합니다. make modules 와 make modules_install 그리고 lilo를 실행 시키는 것을 잊지 마십시요.
SMP 커널의 작동 여부는 어떻게 확인하나요?
cat /proc/cpuinfo
dual PentiumII 의 전형적인 결과:
processor : 0 cpu : 686 model : 3 vendor_id : GenuineIntel [...] bogomips : 267.06 processor : 1 cpu : 686 model : 3 vendor_id : GenuineIntel [...] bogomips : 267.06 |
세밀한 락킹과 멀티스레딩 상태로 전환되는 커널의 상태는?
리눅스 2.2 커널은 시그널 처리와 인터럽트와 몇몇 I/O 의 세밀한 락(lock)처리가 되어있다. 나머지는 천천히 이식되고 있다. 모든 스케줄링은 SMP에 안전하다.
2.3 (다음 버젼인 2.4) 커널은 아주 세밀한 락킹 기능을 가지고 있다. 2.3 커널에서 커다란 커널 락의 사용은 기본적으로 사라지고 대부분의 리눅스 커널의 하부 시스템들은 충분히 스레드화 된다: 네트워킹, VFS, VM, IO, block/page 캐쉬, 스케줄링, 인터럽트, 시그널 등등. (Ingo Molnar)
리눅스 SMP 가 프로세서의 유사성을 지원하나요?
아니요 & 네. 프로세스들을 특정 CPU 위에서 실행하게 하는 길은 없습니다. 그러나 리눅스 스케쥴러는 각 과정들을 위해 프로세서 성향을 가집니다. 그것은 프로세스들을 특정 CPU들에 연결시키게 하는 경향이 있습니다.
네. 관련 사이트 PSET - Processor Sets for the Linux kernel: "이 프로젝트의 목적은 pset의 상호 호환성과 기능을 만들어 줍니다. (SGI에 의해 정의된 - 부분적으로 IRIX 6.4 커널에서 삭제된). 이것은 사용자들이 특정 프로세서(들)의 위에서 프로세스들을 동작하도록 결정하는 것을 가능하게 합니다. 그리고 스레드들은 분리된 프로세서들, 타이밍, 안전 (root 만의 CPU?) 에서 사용될수 있습니다. 그리고 아마도 더 많은 것들도."
이것은 syscall sysmp()에 중점을 둡니다. 이 기능은 어느 기능이 요청되는가에 따라 많은 매개 변수들이 있습니다. 기능들은 다음을 포함합니다.
프로세스/스레드를 특정 CPU에 고정하는것
몇가지 프로세스들을 실행하는 CPU의 능력을 한정하는것
집중되는 실행에서 CPU를 한정 시키는것 (restricting a CPU from running at all)
오로지 한개의 프로세스(부 프로세스들을 포함)를 실행하도록 하는것
CPU의 상태에 대한 정보를 얻는것
바운드 되어 있을지도 모르는 프로세스들의 생성과 파괴 (creating/destroying sets of processors, to which processes may be bound)
SMP 버그는 어디에 보고해야 하나요?
linux-smp@vger.rutgers.edu.
SMP의 성능은 어떤가요?
만약 당신이 SMP 시스템의 성능을 측정하고 싶다면 Cameron MacKinnon에 의해 만들어진 http://www.phy.duke.edu/brahma/benchmarks.smp에서 몇가지 테스트를 해볼수 있습니다.
나에게 SMP가 정말 필요한가요?
만약 당신이 그렇게 물어봐야 한다면 아마도 아닐것 입니다. :) 일반적으로, 멀티 프로세서 시스템은 한개의 프로세서를 가진 시스템에 비해 더 낳은 퍼포먼스를 보여줍니다. 그러나 분명히 파악해야 할것은 CPU 의 수이외에 많은 다른 요인들을 고려할 필요가 있습니다. 예를 들어, 주어진 시스템의 프로세서가 느린 디스크 드라이브 때문에 쉬고 있다면, 이 시스템은 "input/output bound"이며, 프로세서의 추가로 얻는 이익은 적을 것입니다. 만약 시스템이 많은 프로세스들을 동시에 실행하고 있다면 프로세서의 추가로 얻는 이득은 많아집니다. 복수의 프로세서들이 사용될때 SCSI 디스크 드라이브들은 매우 효과적일수 있습니다.(C. Polisher)
두개의 300 MHz 프로세서와 한개의 600 MHz 프로세서는 같은 능력을 수행하는지?
이것은 수행되는 어플리케이션에 따라 다릅니다. 그러나 대부분의 경우는 아닙니다. SMP 는 단일 프로세서에 비해 약간의 오버헤드를 추가합니다. (Wade Hampton). :)
어떻게 하면 여러개의 CPU의 성능을 출력해 볼수 있나요?
Samuel S. Chessman의 덕택으로 몇가지 유용한 유틸리티들이 다음에 있습니다:
http://www.cs.inf.ethz.ch/~rauch/procps.html
근본적으로 이것은 procps v1.12.2 이다. 그리고 SMP를 위한 약간의 패치들.
2.2.x 대를 위한 패치는 이곳에 (Gregory R. Warnes) http://queenbee.fhcrc.org/~warnes/procps
xosview-1.5.1 는 SMP 를 지원합니다. 그리고 2.1.85 이상의 커널에서 /proc/stat 에 cpuX 항목이 있는 경우.
xosview 의 공식 사이트는: http://lore.ece.utexas.edu/~bgrayson/xosview.html
Kumsup Lee 에 의한 2.2.x 커널 패치들이 이곳에 있습니다. http://www.ima.umn.edu/~klee/linux/xosview-1.6.1-5a1.tgz
이외 여러가지 패치들이 http://www-isia.cma.fr/~forissie/smp_kernel_patch/에 있습니다.
당신은 xosview 로 프로세스 스케쥴링을 정확하게 모니터링 할수는 없습니다. xosview 자체가 하나의 프로세스 이며, 스케쥴링에 영향을 주므로 (H. Peter Anvin).
커널 컴파일시 1개의 이상의 프로세스를 실행 시키려면?
다음과 같이 합니다:
# make [modules|zImage|bzImages] MAKE="make -jX" X 는 CPU 숫자입니다. 주의 : 이것은 "make dep" 에서는 적용되지 않습니다. |
2.2 대 커널에서는 /usr/src/linux/Documentation/smp.txt 문서를 참고하세요.
복수의 프로세서들을 사용하기 위한 충분한 메모리와 입출력 속도(하드 디스크등의) 가 아니라면 컴파일과정에 더 지연을 일으킬수 있습니다. make MAKE="make -j 2" -j 2 는 실제로 단일 프로세서에서도 효과를 볼수 있습니다. (Ralf B�chle).
왜 time 명령어가 부정확하게 작동하는지? (Joel Marchand)
2.x 대의 커널에서 time 명령어의 결과는 부정확합니다. 유저와 시스템의 합은 맞습니다만, 유저와 시스템 사이에 spreading (배치? 발생?)되는 시간은 정확하지 않습니다.
더 자세하게: 부트 CPU 이외의 프로세서들에 의해 사용되는 시간들이 시스템의 시간과 같다고 생각되기 때문이다. 만일 당신이 프로그램의 시간을 잰다면, 사용자 시간과 시스템의 시간을 더한다면 그것은 거의 정확할 것이다. (시스템 시간을 계산하는 시간을 제외한) (Jakob �stergaard).
이 버그는 2.2 커널에서 수정되었습니다.
Jakob �stergaard 에 의해
SMP 리눅스를 위한 다중 스레드 프로그래밍에 대한 섹션입니다.
POSIX 스레드
PVM / MPI Message Passing Libraries
fork() -- 다중 프로세스
fork() 와 PVM/MPI는 일반적으로 메모리를 공유하지 않아, IPC 또는 메시징 API 에 의해 소통되기도 하며, 이것은 이번장에서 더이상 설명되지는 않을 것이며, 이것들은 단일 프로세서와 클러스터에서도 사용되는 것이므로 SMP 에 특정되어 있지도 않습니다.
오로지 POSIX 스레드만이 시스템 자원을 공유하는 것(특히 메모리)과 같은 다중 스레드를 제공한다. 이것은 SMP 머신을 특별하게 하는 것이며, 많은 프로세서들이 메모리를 공유하는 것이 가능하다. SMP에서 양쪽(또는 그이상)의 프로세서를 사용하기 위해서는 커널-스레드-라이브러리를 사용한다. 좋은 라이브러리는 LinuxThreads - Xavier Leroy에 의해 만들어진 pthread 라이브러리이다. 새로운 리눅스 배포본들은 이 라이브러리를 기본으로 포함하고 있다. 그러므로, 당신은 커널 스레드 사용을 위해 따로 패키지를 사용할 필요가 없다.
어플리케이션 수준에서 커널-스레딩을 사용하지 않는 스레드들 (그리고 POSIX 스레드들)의 실현이 있다. 이 스레드 꾸러미들은 한개의 과정에서 스레딩을 유지한다. 그러므로 SMP를 이용하지 말라. 그러나 그들은 많은 적용에 좋고, 한개의 프로세서 시스템에 관한 커널-스레드들 보다 실제로 더 빠른 경향이 있다.
다중-스레딩은 Un*x 세계에서 인기가 없었습니다. 몇가지 이유로, 복수의 프로세스 또는 스레드를 필요로 하는 어플리케이션을 위해, 대부분은 fork()를 사용하여 씌여졌습니다. 그러므로, 스레드 사용에 접근할때, 서로 호환되지 않는(thread-ready하지 않은) 라이브러리, 컴파일러 그리고 디버거등이 문제가 됩니다. GNU/Linux 또한 예외는 아닙니다. 다음의 몇장에서 현재 가능한 것과 그렇지 않은 것을 설명합니다.
오래된 C 라이브러리는 스레드에 안전하지 않습니다. GNU LibC (glibc), 또한 libc6로 알려진 라이브러리를 사용하는 것은 매우 중요합니다. 이전 버젼들도 당연히 사용가능은 하나, 당신을 좀더 괴롭혀 시스템 업그레이드의 원인이 될것입니다. 아마도 :)
만약 프로그램의 디버깅을 위해 GDB 를 사용하고자 한다면 다음을 보십시요.
GNU/Linux 를 위한 풍부한 프로그래밍 언어가 있습니다, 그리고 그중에 대부분은 어떻게 든 스레드(심지어 Ada 와 자바와 같은 언어들도) 를 사용할수 있습니다.
이 장에서는 C 와 C++ 에 관해서만 기술할것입니다. 만약 당신이 다른 언어로 SMP 프로그래밍의 경험이 있다면 알려주세요.
GNU C 와 C++, EGCS C 와 C++ 컴파일러들은 표준의 C 라이브러리에서 스레드를 잘 지원한다. (glibc). 그러나 여기에 약간의 이슈들이 있다.
C 와 C++ 의 컴파일중, -D_REENTRANT 를 컴파일러 커맨드 라인에서 정의한다. 이것은 에러 처리 기능을 위해 필요하다. (errno variable과 같은).
C++ 를 사용할때에 만약 두개의 스레드가 동시에 throw exceptions 한다면, 이 프로그램은 segfault 될것입니다. 그리고, 컴파일러는 스레드-안전 하지 않은 코드를 생성할 것입니다. 회피 방법은 pthread_mutex_lock(&global_exception_lock) 을 모든 constructor(s) 클래스 throw()에 넣는다. , 그리고 상응하는 pthread_mutex_unlock(...) 를 추가합니다. 이것은 보기 좋지는 않으나, 작동은 합니다. 이 방법은 Markus Ferch에 의해 제시 되었습니다.
GNU 디버거 GDB 버젼 4.18은 스레드를 바르게 취급할 것입니다. 대부분의 리눅스 배포본들이 패치된(thread-aware)한 gdb 를 제공합니다.
단지, 스레드와 일하기 위해 glibc를 패치하는 것은 불필요합니다. 만약 당신이 소프트웨어를 디버깅 할 필요가 없다면( 개발 시스템을 제외한, 대부분의 시스템에서는 그럴것이다.) glibc의 패치는 불필요 합니다.
코어 덤프는 복수의 스레드들에 의해 생기지 않습니다. 어떻게든, 코어 덤프는 프로그램 전체가 아닌 현재 실행중인 스레드에 붙여집니다. 그러므로, 무엇이든지 디버깅을 할때 디버거상에서 실행시키세요. Note that core-dumps are of no use when using multiple threads. Somehow, the core dump is attached to one of the currently running threads, and not to the program as a whole. Therefore, whenever you are debugging anything, run it from the debugger.
힌트: 만약 스레드가 100% CPU time을 잡아먹고 있다면, 그 이유를 알아낼수 없을것입니다. 이 경우 좋은 방법이 있습니다. : GDB 상이 아니라, 쉘상에서 바로 프로그램을 실행 시킵니다. top 으로 그 프로그램의 PID를 알아냅니다. 다음 GDB를 다음과 같이 실행합니다. gdb 프로그램 pid. 이것은 GDB를 지정한 PID 프로세스에 적용하게 하며, 스레드는 멈출 것 입니다. 이제 당신은 그 스레드에 해당하는 GDB 세션과 bt를 사용할수 있으며, 무엇이 일어나고 있는지 알수 있습니다.
ElectricFence: 이 라이브러리는 스레드에서 안전하지 않습니다. 그러나 이것에 mutex lock을 삽입함으로써 SMP 환경에서의 사용이 가능해 집니다.
병렬 프로그래밍에 관한 더 많은 정보를 어디서 찾을수 있나요?
많은 쓸모있는 정보를 여기서 찾을수 있습니다. 리눅스를 이용한 병렬 처리
또한 리눅스 스레드 FAQ
스레드화 프로그램과 라이브러리들은 어디에?
다음을 보세요: 리눅스 멀티 스레드 프로그램 (저는 하이퍼 링크를 좋아합니다 그거 아세요? ;))
참고가 될 라이브러리들:
David Buccarelli 와 Andreas Schiffler 그리고 Emil Briggs의 덕택 으로 다중 스레드 버젼(몇몇 OpenGL 벤치마크에 의하면 5-30% 의 속도 증가를 제공하는 버젼이 있습니다. [1998-05-11]). 다중 스레드는 현재 실험적인 옵션으로서 메사 라이브러리에 포함 되었습니다. 더 자세한 것은 Mesa 라이브러리을 참고하세요.
펜티엄 프로 최적화 BLAS 그리고 인텔 리눅스를 위한 FFTs
멀티 스레드 BLAS 는 지금은 존재하지 않습니다만, 다중 프로세스 라이브러리는 1998-05-27 에 설계 되었습니다. Blas News.
Emil Briggs (다중 스레드 메사를 만들고 있는 사람중 하나인) 에 의해 다중 스레드 GIMP 플러그인들이 있습니다. http://nemo.physics.ncsu.edu/~briggs/gimp/index.html