Performance
컴퓨터의 성능을 결정짓는 요소들은 매우 많습니다. 그리고 성능을 보여주는 지표 또한 매우 많습니다. 이에 대해 살펴봅니다.
Response Time and Throughput
- Response time(응답 시간): 응답 시간은 어떤 태스크를 수행하는데 걸리는 시간을 말합니다. 만약 성능을 향상시키기 위해 CPU는 더 빠른 버전으로 바꿨다면 이는 응답 시간에 포커스를 둔 성능 향상입니다.
- Throughput: 단위 시간동안 한 일입니다. 다시 말해, 단위 시간당 얼마나 많은 일을 해결할 수 있는가? 입니다. 만약 성능을 향상시키기 위해 CPU의 개수를 늘렸다면 이는 Throughput에 포커스를 둔 성능 향상입니다.
Relative Performance
Response Time에 대한 performance를 먼저 살펴보겠습니다.그렇다면 이때 performance는 1/Excution Time으로 볼 수 있습니다. 실행 시간이 줄어들 수록 성능은 향상되기에 역수관계라고 할 수 있습니다.
그렇다면 이때 X가 Y보다 n배 빠르다면 다음과 같은 식이 성립할 것입니다:
Measuring Excution Time
이때 실행 시간을 측정하는 데에 두 가지 방법이 존재합니다.
- Elapsed time(경과 시간, Wall clock time, Response time): 이는 어떤 프로세스를 실행하는데 걸리 총 시간을 말합니다. 이는 CPU 연산 시간 뿐만 아니라, I/O작업, OS overhead등의 모든 작업들에 걸린 시간들을 포함합니다.
- CPU time: 이는 주어진 job을 CPU에서 처리하는데 걸린 시간을 말합니다. 이는 Elapsed time과 달리 CPU 연산 시간만을 말합니다.
- 경과 시간이나 CPU시간 모두 프로그램이 실행되는 환경이 달라질 수 있기 때문에 같은 프로그램일지라도 실행할 때마다 시간이 달라질 수 있습니다.
CPU Clocking
CPU Clock은 컴퓨터 프로세서의 동작 기본 단위를 말합니다. 이는 초당 주기로 측정하며 클럭 주파수로 헤르츠(Hz)단위를 사용합니다. 일반적으로 CPU의 데이터 이동이나 연산은 Clock 주기 동안 이루어집니다. 그렇기에 이 클럭 속도는 CPU 속도의 지표로 사용될 수 있습니다.
이때 한 클럭동안 걸리는 시간을 Clock Period라고 부르고, 단위는 Pico second를 사용합니다. 만약 250ps의 CPU 주기를 갖는다면 한 클럭에 250 x 10^-12second의 주기를 갖는다고 해석합니다.
또한 CPU의 초당 클럭 사이클 수를 Clock Frequency라고 부릅니다. 만약 4.0GHz의 주기를 갖는다면 1초에 4억번의 사이클을 돈다고 해석합니다.
CPU Time
그렇다면 성능의 기준이 되는 CPU Time은 어떻게 구할 수 있을까요?
간단합니다.
(어떤 동작을 하는데 소요한 사이클의 수) x (사이클의 주기)
입니다.
이때 사이클의 주기는 사이클의 주파수의 역수이므로 다음과 같은 식이 성립합니다:
이 식에 따르면 성능을 향상하기 위해서는 두 가지 방법이 존재합니다. (1) 먼저 clock cycle의 수를 줄이는 방법입니다. 매우 좋은 알고리즘이나, ISA를 통해 해당 명령을 수행하는데 필요한 사이클의 수를 줄이면 성능이 좋아진다는 것입니다. (2) 그 다음으로는 clock cycle time을 줄이는 것입니다. 다시 말해 clock 주파수를 늘리는 것입니다. 매우 좋은 CPU를 구매해 clock rate가 증가한다면 성능이 좋아진다는 것입니다.
예를 들어보겠습니다.
Computer A는 2GHz clock을 갖고 있으며, A로는 10s의 CPU Time이 걸리는 작업이 있습니다.
이때 Computer B를 디자인 할 때, CPU Time을 6s로 맞추고 싶습니다. 그렇다면 clock rate를 얼마나 빠르게 해야할까요? 단 이를 위해 클럭 속도를 향상시키면, B는 A보다 1.2배의 clock cycle이 필요하다고 가정합니다.
예시에 따르면 clock rate를 두 배 늘리면 CPU Time이 0.6배 줄어듬을 알 수 있습니다.
Instruction Count and CPI
좀 더 자세하게 들어가겠습니다.
Clock cycle은 명령에 필요한 사이클의 수입니다. 그렇다면 명령의 수가 많다면 이는 어떻게 계산할 수 있을까요?
Clock cycle은
(해당 프로그램의 전체 명령 수) x (명령 당 cycle의 수)
입니다. 이때 Cycle per Instruction (CPI)는 평균 CPI입니다. 이 식을 통해 다시 CPU Time을 정의해보면 위 그림과 같습니다.
그렇다면 Instruction Count는 어떻게 정해질까요?
일반적으로 프로그램의 종류나 ISA, compiler의 종류에 의해 결정됩니다. 예를 들어 효율적으로 컴파일링하는 컴파일러가 있다면 같은 프로그램이더라도 수행해야하는 instruction의 수가 줄어들 수 있습니다. 이는 ISA도 마찬가지입니다.
그렇다면 CPI는 어떻게 정해질까요?
CPI는 일반적으로 IC와 마찬가지로 instruction의 종류나 CPU 하드웨어의 구조 등에 의해 결정됩니다. 예를 들어 간단한 명령의 경우 한 instruction당 cycle의 수가 늘어날 수 있습니다.
예를 들어,
Computer A는 Cycle time이 250ps이고 평균 CPI = 2
Computer B는 Cycle time이 500ps이고 평균 CPI = 1.2
같은 ISA를 사용할 때(=같은 instruction count) 어느 컴퓨터가 더 빠르고 얼마나 빠를까요?
얼마나 빠른지는 CPU Time과 관련됩니다.
CPU_Time_B / CPU_Time_A
= 1.2 x Instruction_Count_B x 500ps / 2.0 x Instruction_Count_A x 250ps
= (Instruction_Count_B = Instruction_Count_A)
= 2.4 / 2.0 = 1.2배
A가 B보다 1.2배 빠릅니다. 놀랍게도 CPI가 B보다 크지만 Cycle time이 B에 비해 작기 때문에 결과적인 성능에서는 A가 더 우수함을 알 수 있습니다.
CPI in More Detail
CPI에 대해 자세히 살펴보겠습니다.
각 명령 1부터 n까지에 대해 Clock cycle을 다음과 같이 정의할 수 있습니다:
이때 평균 CPI는 전체 Clock cycle을 Instruction count로 나눈 것입니다(CPI가 Cycles Per Instruction이니까). 따라서 다시 식을 전개해보면:
즉 average CPI는
(해당 instruction의 CPI) x (해당 instruction의 상대 빈도)
로 계산할 수 있습니다.
예를 들어보겠습니다.
위 그림과 같은 상황이 주어졌을 때,
sequence A와 sequence B의 평균 CPI를 구하면 다음과 같습니다:
Clock_Cycle_1
= CPI_A x Instruction_Count_A + CPI_B x Instruction_Count_B + CPI_C x Instruction_Count_C
= (1 x 2) + (2 x 1) + (3 x 2) = 10
Avg.CPI_1 = 10 / Instruction_Count_1 = 10 / 5 = 2
Clock_Cycle_2
= CPI_A x Instruction_Count_A + CPI_B x Instruction_Count_B + CPI_C x Instruction_Count_C
= (1 x 4) + (2 x 1) + (3 x 1) = 9
Avg.CPI_2 = 10 / Instruction_Count_2 = 9 / 6 = 1.5
만약 같은 clock rate를 갖는다면,
Instruction Count은 sequence 2가 더 많음에도 불구하고
sequence 1에 비해 더 빠른 CPU Time과 더 작은 평균 CPI를 기록함을 알 수 있습니다.
Performance Summary
이때 각 요소에 영향을 미치는 요인들입니다:
- 알고리즘: 알고리즘은 Instruction Count에 영향을 미칩니다. 좋은 알고리즘은 같은 기능을 수행하더라도 더 적은 수의 instruction을 필요로하기 때문입니다. 그리고 CPI에 영향을 미칠 수도 있습니다. 최적화 알고리즘은 CPU에 부담을 줄여 instruction당 소모하는 cycle의 수를 줄일 수도 있습니다.
- 프로그래밍 언어: 언어는 Instruction Count에 영향을 미칩니다. C언어의 경우 python에 비해 기계 친화적이기에 필요한 Instruction의 수를 적게 가져갈 수 있습니다. CPI도 마찬가지의 이유로 영향을 받습니다.
- 컴파일러: 프로그래밍 언어와 유사한 이유로 IC, CPI 모두 영향을 미칩니다.
- Instruction Set Architecture(ISA): 위와 비슷한 이유로 IC와 CPI에 영향을 미칠 수 있습니다. 또한 Clock cycle에도 영향을 줄 수 있습니다. ISA 자체가 clock 속도를 직접 결정하는 것은 아니지만 CPU의 설계 방식에 영향을 주어 이를 증가시키거나 감소시킬 수 있습니다. RISC ISA (e.g., ARM, RISC-V)의 경우 단순한 명령어 구조 덕분에 고속 클럭 설계가 가능합니다. 하지만 CISC ISA (e.g., x86)의 경우 복잡한 명령어 구조로 인해 클럭 속도 상승에 제한이 걸릴 가능성이 존재합니다.