프로세스를 더 빠르게 실행할 수 있도록 (예 : 파이썬 계산) CPU의 100 %를 모두 "켜는"간단한 방법이 있는지 궁금합니다.
1) 이것이 가능합니까?
2) 다시 정상으로 되돌릴 수있는 쉬운 방법이 있습니까?
3) 원하는 경우 더 적은 CPU를 사용하는 방법이 있습니까?
다음과 같은 명령 줄 상호 작용을 생각하고 있습니다.
pi@raspberry:~ $ sudo turnOnFourCores python run.py
프로세스를 더 빠르게 실행할 수 있도록 (예 : 파이썬 계산) CPU의 100 %를 모두 "켜는"간단한 방법이 있는지 궁금합니다.
1) 이것이 가능합니까?
2) 다시 정상으로 되돌릴 수있는 쉬운 방법이 있습니까?
3) 원하는 경우 더 적은 CPU를 사용하는 방법이 있습니까?
다음과 같은 명령 줄 상호 작용을 생각하고 있습니다.
pi@raspberry:~ $ sudo turnOnFourCores python run.py
답변:
기본적으로 모든 컴퓨터는 가능한 경우 모든 코어를 사용하려고합니다. 그러나 응용 프로그램이 다중 스레드 인 경우에만이를 수행 할 수 있습니다. 그렇지 않은 경우 (즉, threading
모듈을 사용하지 않는 Python 스크립트 ) 최대 하나의 코어 만 사용할 수 있습니다. 이는 4 코어 CPU에서 CPU의 25 %에 해당합니다. 여러 코어를 사용하도록 스크립트를 수정하려면 계산을 여러 부분으로 나누고 Python 문서에 표시된대로 멀티 스레드 할 수 있습니다 .
Anon이 대답 했듯이 Python의 GIL (Global Interpreter Lock)을 사용하지 않으면 작동하지 않습니다. 이를 통해 작업을 동시에 (겉보기에) 수행 할 수 있지만 여러 코어에서 코드를 실행할 수는 없습니다. C로 작성된 모듈 (예 : numpy) 을 사용하는 경우 여러 코어를 사용하여 해당 제한을 극복 할 수 있습니다 . 또한, 이것이 옵션이 아닌 경우, Python은 multiprocessing을 제공 하여 여러 코어에서 모든 작업을 실행할 수 있습니다.
프로세스를 더 빠르게 실행할 수 있도록 (예 : 파이썬 계산) CPU의 100 %를 모두 "켜는"간단한 방법이 있는지 궁금합니다.
당신이 암시하고 있다고 생각한다는 의미는 아닙니다. 이것은 pi에만 해당되는 문제가 아니며 논리적 제약이기도합니다.
컴퓨터 자체는 현재 단일 스레드 로 실행되는 프로세스 를 병렬로 실행할 수 있는지 결정할 수있는 용량이 충분하지 않습니다 . 이 용량을 가질 수있는 시점에서는 컴퓨터 프로그래머가 필요하지 않습니다.이 작업을 수행 할 수있는 컴퓨터 시스템은 자체 코드 1을 작성할 수도 있기 때문 입니다.
다음과 같은 간단한 수학 표현을 고려하십시오.
(4 + 2) * 17 / (3 + 6)
병렬로 계산할 가능성이 있지만 논리적으로 제한되어 있습니다. 나는 두 개 이상의 스레드에 아무런 의미가 없다고 말하고 심지어는 하나만 될 것입니다.
#1 a) 4 + 2 b) 6 * 17 c) 102 / 9
#2 a) 3 + 6
스레드 # 2는 스레드 # 1에 의해 단계 C에서 사용 된 3 + 6 = 9를 계산하여 한 단계 절약함으로써 기여했습니다. 그러나 그것은 병렬 처리가 유용하게 도달하는 한입니다. 스레드 # 2 가 17 / 9를 계산할 수 있지만 # 1이 6 * 17을 수행하는 동안, 다시 수행 할 수없는 동일한 목표에 대한 두 개의 다른 경로가 있으므로 그렇게하는 것은 의미가 없습니다. 즉, # 2는 계속 작동 할 수 있습니다.
b) 17 / 9 c) 1.888 * 6
스레드 # 1 (11.333)과 동일한 결과로 끝나지만 A 단계 이후에는 서로 도움이되지 않았으므로이 목표를 추구하는 것은 시간 낭비입니다.
(이 예제는 문자 그대로가 아니라 논리적 인 원리를 보여주기위한 것입니다. 사용자 코드에서 작업이 스레드되는 규모는 훨씬 크지 만 멀티 스레드 프로그래밍에 대한 실질적인 교훈은 필요하지 않습니다. 여기에서 아이디어를 파악하십시오.)
여러 프로세서를 악용하려면 코드를 작성해야합니다. 단순히 아무 것도 가져 가서 "오 4 코어를 모두 사용하고 더 빨리해라!"라고 말할 수는 없습니다. 그것은 일어날 일이 아닙니다. 논리적으로, 많은 (.. 또는 대부분) 문제와 작업은 병렬로 발생할 수없는 단계와 관련 이 있으며 순서대로 발생해야합니다.
1. 그러나 아래의 Felix Dombek의 의견을보십시오. 저는 AI 전문가가 아닙니다. Peter Corde의 의견에 따르면, OS에서 현대적인 명령어 세트와 프로세서를 활용하여 매우 세밀하게 정리 된 것을 병렬 방식으로 최적화 할 수 있으며, 하드웨어 파이프 라인 은 코어를 통하지 않더라도이를 수행합니다. core는 하나 이상의 작업이 진행 중이며 최종 실행 전에 다양한 지점에서 명령 스트림에서 작동합니다. 나는 그것이 당신이 얻는 것보다 다소 적은 것으로 생각하면서 여기에서 사용자 스레드 주제를 고수하려고했습니다.
add
명령을 나란히 배치하여 ILP를 계속 활용할 수 있으므로 두 명령을 모두 동일하게 실행할 수 있습니다 클럭 사이클. 그러나 다음 곱하기 및 나누기 나머지는 데이터 종속성에 따라 직렬화됩니다.
다중 코어를 사용하려면 스레드 수준 병렬 처리 를 OS에 명시 적으로 노출해야하며 , 일반적으로 프로그래머는 다중 스레드 프로그램을 작성해야합니다. (또는로 컴파일하는 것과 같이 다른 입력에서 단일 스레드 프로그램을 여러 번 실행하려면 make -j4
)
그러나 일부 언어의 컴파일러는 자동 병렬화를 지원합니다. 예를 들어 OpenMP를 사용하는 C 또는 C ++는 일반 for()
루프를 여러 스레드를 시작하는 프로그램으로 컴파일 할 수 있습니다 .
#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
A[i] = B[i] * constant + C[i];
}
그러나 여전히 이것은 프로그램을 작성하거나 컴파일 할 때 발생해야합니다. 현재 하드웨어 및 OS가 다중 코어를 사용하여 단일 스레드 프로그램의 속도를 높일 수있는 방법이 없습니다.
관련 : 단일 스레드는 여러 코어에서 어떻게 실행됩니까? : 답변 : 그렇지 않습니다. 그러나 단일 CPU 코어가 한 번에 하나의 명령보다 빠르게 단일 스레드를 실행하기 위해 찾아서 이용하는 명령 수준 병렬 처리와 같은 다른 종류의 병렬 처리 가 있습니다.
이 질문에 대한 나의 대답은 최신 CPU가 세분화 된 명령 수준 병렬 처리 방법을 찾고 활용하는 방법에 대한 세부 사항 중 일부에 있습니다. (대부분 x86에 중점을 둡니다). 이는 여러 개의 명령어를 한 번에 실행하여 일반 CPU가 작동하는 방식의 일부일 뿐이며 특별히 활성화 할 필요는 없습니다. (프로그램을 실행하는 동안 CPU가 실행하는 클럭 당 명령 수 또는 기타 측정 값을 확인할 수있는 성능 카운터가 있습니다.)
RPi3은 순서대로 ARM Cortex-A53 CPU 코어를 사용 합니다. 각 코어는 2 와이드 수퍼 스칼라 (ILP가 허용하는 한 클럭 당 2 개의 명령)이지만 더 많은 명령 수준 병렬 처리를 찾고 대기 시간을 숨기기 위해 명령을 재정렬 할 수 없습니다.
여전히 CPU는 파이프 라인이므로 파이프 라인 끝에서 페치 및 디코딩에서 라이트 백 단계까지의 총 명령 수는 중요합니다. 데이터 종속성이 제한을 두지 않는 경우 CPU가 작업중인 각 파이프 라인 단계에 2 개의 명령어가있을 수 있으며 클럭 당 2 개의 명령어 처리량이 있습니다. (2 와이드의 의미입니다.)
명령을 순서대로 실행할 수는 없지만주의해서 명령을 정렬하면 (보통 컴파일러에서) 출력을 준비하기 위해 여러주기가 걸리는 명령의 대기 시간을 숨길 수 있습니다. (예 : 캐시에 부딪 치거나로드가 여러 번 발생하더라도로드가 다음 사이클에 대비되는 추가 대 여러 사이클이 소요됨). 비결은 asm 명령어를 주문하여 결과를 생성하는 명령어와이를 사용하는 명령어 사이에 여러 개의 독립적 명령어가 있도록하는 것입니다.
소프트웨어 (컴파일러)가 명령을 정적으로 예약하는 것은 프로그램 순서대로 실행되는 환상을 유지하면서 내부적으로 재정렬 할 수있는 하드웨어를 갖는 것보다 취하기 쉽습니다. 캐시 미스는 예측할 수 없기 때문에 컴파일러가 명령 순서를 변경하는 작은 비 순차적 창처럼 훌륭한 작업을 수행하는 것은 매우 어렵고 컴파일 타임에 함수 호출에서 종속성 체인을 분석하기가 어렵습니다. 또한 레지스터 수는 하드웨어 레지스터 이름 변경없이 제한됩니다.
이 모든 것이 코드가 원하는 것보다 느리게 실행될 때 작은 편안함입니다. 물론 Cortex-A53에는 후드 아래에 멋진 것들이 많이 있지만 Cortex-A57 에는 후드 아래에 더 멋진 것들이 있습니다 (시계 당 최대 3 개의 명령을 순서대로 실행하는 것과 같이). Skylake와 같은 큰 x86 CPU (클럭 속도 차이는 말할 것도 없습니다).
Cortex-A53은 컴퓨터 아키텍처 수업에서 배우게 될 독창적 인 MIPS와 같은 https://en.wikipedia.org/wiki/Classic_RISC_pipeline 과 비교할 때 매우 환상적 이지만 현대 표준으로는 매우 저렴합니다.
java
, 아니 myapp.jar
, 그것은 확실히 단일 스레드 없습니다.
이것은 CPU가 작동하는 방식이 아닙니다.
현재로서는 CPU가 섭씨 80도 이상의 온도 관련 문제로 인해 조절되지 않는 것으로 가정하여 100 % 사용량으로 완벽하게 실행할 수 있습니다. 즉, 일반적으로 CPU가 100 %로 멈춰있는 것을보고 싶지 않습니다. 일상적으로 CPU 사용률이 100 % 인 경우 프로세서가 처리하기에 너무 많은 것 같습니다. 이로 인해 말더듬이 발생하고 일반적으로 불행한 사용자 경험이 발생합니다.
보다 실제적인 것과 비교하면 CPU 사용률은 자동차와 매우 비슷합니다. 차는 100mph를 주행 할 수 있지만 속도계가 그 아래에서 무언가를 크게 읽을 가능성이 높습니다. 시내에있을 때, 약 25mph를 절대로 얻지 못할 수도 있습니다. 그러나 차가 100mph를 갈 수 있다는 것은 변하지 않습니다. 가속기를 너무 세게 밀지 않았습니다.
RPi가 더 많은 일을하게한다면 (가속기를 더 많이 누르십시오), CPU 사용률 수치가 올라갑니다. 예를 들어, yes
터미널 창에서 명령을 실행할 때 CPU 사용률을보십시오 ( ctrl+c
터미널 명령 을 종료하는 것을 기억하십시오 ). 이렇게하면 4 개의 CPU 코어 중 하나를 최대로 사용하므로 CPU가 25 % 증가합니다.
다른 답변은 자세하게 설명되어 있지만 귀하의 질문을 구체적으로 다루지는 않습니다.
NB :
전체적으로 파이의 성능을 향상시키려는 경우 오버 클럭킹을 살펴볼 수 있습니다. 이렇게하면 CPU가 더 빠른 속도로 실행됩니다. 단점은 열 생산 증가, 프로세서 수명 단축 및 전력 소비 증가입니다.
가능한 경우 스크립트를 매개 변수화하고 별도의 Python 프로세스에서 실행합니다. 예를 들면 다음과 같습니다.
cat parameters.txt | xargs -n1 -P4 python run.py
다른 대안은 이미 언급 한 멀티 프로세싱 라이브러리로, 파이썬 프로세스를 포크 앤 조인 할 수 있습니다. 그러나 계산을 실행하려는 매개 변수 목록 (예 : 파일 이름)도 있어야합니다.
map
했지만 분명히 매우 정교한 공유 메모리 구성도 가지고 있습니다.
OP가 멀티 코어 / 멀티 스레드 프로그래밍의 개념을 완전히 이해하지 못하고 알고리즘을 난처한 병렬 문제 로 쉽게 만들 수 없다면 멀티 코어의 100 %를 완전히 활용하는 것이 어려울 것이라고 생각합니다 .
자세한 내용은 잘 알려진 기사 제목 "무료 점심 식사가 끝났습니다" http://www.gotw.ca/publications/concurrency-ddj.htm에 대한 자세한 내용을 참조하십시오.
이 모든 대답은 다른 방식으로 옳지 만 운영 체제는 자동으로 다른 코어를 사용하여 부하를 분산시키는 것이 사실입니다. 간단한 파이썬 프로그램 (temp.py say)으로 이것을 볼 수 있습니다
while True:
x = 1.0
RPi 데스크탑에서 터미널을 열고 $ top
프로세서 작동을 보여주는 유형 을 입력하십시오 . 그런 다음 다른 터미널을 열면 python3 temp.py
python3 작업이 100 % 프로세서 시간으로 증가하는 것을 볼 수 있습니다. 그런 다음 다른 터미널을 열고 프로세스를 반복하고 400 %까지 어떻게 이동하는지 확인하십시오. 따라서 @Shadow가 언급 한 것처럼 한 수준에서 간단하고 기본값입니다. 그러나 다른 사람들이 설명했듯이 병렬 처리를 사용할 수있는 프로그램을 설계하는 것은 쉽지 않습니다.
OP가 그의 질문에 파이썬을 지정하지 않았기 때문에 Raspberry Pi에서 잘 작동하고 동시성을 사용하는 매우 쉬운 방법이있는 두 가지 더 현대적인 언어를 제안하고 싶습니다.
내가 가장 좋아하는 언어는 Rust 언어입니다. Pi에 프로그램을 작성하고 컴파일했습니다. Rust는 많은 유형의 포인터 및 경쟁 조건 버그를 방지하여 동시 코드를 더 쉽고 안전하게 작성할 수 있다는 점에서 훌륭합니다. Rust는 시스템 프로그래밍 언어를위한 것이지만 C가 할 수있는 모든 것을 할 수 있습니다.
이러한 다른 언어는 Go입니다 (검색하기 쉽도록 Golang이라고도 함). Go는 Google 팀에서 만들었으며 상당히 성숙한 언어입니다. Go에서 코 루틴을 만드는 것은 쉬운데,이를 "Go routines"라고 부릅니다.
이 두 언어는 모두 Raspberry Pi, 심지어 Pi Zero에서도 코드를 컴파일 할 수 있습니다. 그러나 둘 다 큰 프로그램에 적합한 빠른 컴퓨터에서 크로스 컴파일 할 수 있습니다.