1.
지난 한주동안 HP서버를 열심히 튜닝하였습니다. 공장 출시한 값으로 설정한 서버를 Low Latency Server로 바꾸는 일이죠. 문서는 HP에서 나온 문서입니다.
Configuring and Tuning HP ProLiant Servers for Low-Latency Applications
오래전 BIOS 설정을 할 때 C3-State관리가 중요하다는 사실을 알고 있기 때문에 BIOS설정을 먼저 하였습니다.
그런데 HP문서를 보면서 C State를 BIOS뿐 아니라 커널에서도 설정을 해준다는 사실을 처음 알았습니다. 이 문장입니다.
Edit /boot/grub/grub.conf and add “nosoftlockup intel_idle.max_cstate=0 mce=ignore_ce” to the kernel line
nosoftlockup prevents RHEL from logging an event when a high-priority thread executes continuously on a core for longer than the soft lockup threshold. intel_idle.max_cstate=0 prevents the kernel from overriding the BIOS C-state setting. mce=ignore_ce prevents Linux from initiating a poll every five minutes of the Machine Check Banks for correctable errors, which can cause latency spikes.
2.
HP서버만 해당하는지 조사를 해보니 Dell 서버도 같았습니다. Controlling Processor C-State Usage in Linux라는 제목으로 자료까지 내었더군요. 아주 상세히 설명해놓은 자료입니다.
그런데 설정을 해놓고 실제로 어떻게 동작하는지를 확인하여야 합니다. 이를 위해 도움을 주는 것이 PowerTOP입니다. Intel이 개발하여 공급하는 오픈소스 프로그램입니다.
가장 최근 버전으로 설치하시려면 위에서 프로그램 소스를 받아서 컴파일을 하시면 됩니다. CentOS에서 그냥 패키지를 설치하시려면 아래와 같이 하시면 됩니다. 그러면 1.11버전이 깔립니다. 좀더 자세한 정보를 알고 싶으면 RedHat의 PowerTOP을 참고하세요.
1 |
yum install powertop |
ZeroAOS의 개발서버에 설치를 해서 실행을 시켜보았습니다. 아래와 같습니다.
튜닝을 하지 않은 상태입니다. C3 State의 비중이 앞도적입니다. 만약 매매중이라고 하면 High Latency입니다. wakeup을 많이 일으키는 프로세스를 확인해보았습니다. Ztermsvr입니다. ZTerminal로부터의 Request를 처리하는 서버입니다. 구조적으로 개선하여야 합니다.
왜 C-State관리가 중요할까요?
위의 그림을 보시면 C3(C4) State는 L1/L2 메모리를 깨끗히 청소하고 – L2는 일부 – CPU동작을 멈춥니다. 다시 동작을 하도록 하여 C0으로 가려면 wakeup time이 필요합니다. 이에 대한 설명을 하는 자료입니다.
On a typical processor, C1 will just turn off the processor clock, while C2 turns off other clocks in the system and C3 will actively power down parts of the CPU. On such a system, it would make sense to spend as much time as possible in the C3 state; indeed, while this sentence is being typed, the system is in C3 about 97% of the time. One might have thought that emacs could do a better job of hogging the CPU, but even emacs is no challenge for modern processors. The C1 state is not used at all, while a small amount of time is spent in C2.
One might wonder why the system bothers with anything but C3 at all; why not insist on the most nothing for the buck? The answer, of course, is that C3 has a cost. The 57µs exit latency means that the system must commit to doing nothing for a fair while. Bringing the processor back up also consumes power in its own right, and the ancillary costs – the C3 state might cause the flushing of the L2 cache – also hurt. So it’s only worth going into C3 if the power savings will be real and if the system knows that it will not have to respond to anything with less than 57µs latency. If those conditions do not hold, it makes more sense to use a different idle state. Making that decision is the cpuidle subsystem’s job.
The cpuidle subsystem중에서
그러면 구체적인 Wakeup Time은 얼마일까요? 위의 사례는 57마이크로초라고 했습니다. 개발서버에서 아래와 같이 해서 확인해보았습니다.
1 2 |
[root@ium powertop-2.3]# cat /sys/devices/system/cpu/cpu0/cpuidle/state3/latency 104 |
위의 숫자는 Exit Latency입니다. C-State를 관리하지 않으면 그 만큼 손해를 봅니다. 이번 경험을 보면 C-State를 설정하기전과 한 후를 비교하면 1/2로 줄어들었습니다.
참고로 어떤 이의 실험결과를 소개합니다. 다양한 실험을 하였습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Test #1: processor.max_cstate=0 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 2.37 3.06 2.67 0.03 0.13 97.47 0.00 67.31 Test #2: processor.max_cstate=1 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.04 2.16 2.67 0.04 0.55 99.37 4.76 88.00 Test #3: processor.max_cstate=0 intel_idle.max_cstate=0 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.02 2.20 2.67 99.98 0.00 0.00 0.00 0.00 Test #4: processor.max_cstate=1 intel_idle.max_cstate=0 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.02 2.29 2.67 99.98 0.00 0.00 0.00 0.00 Test #5: intel_idle.max_cstate=0 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.02 2.19 2.67 99.98 0.00 0.00 0.00 0.00 # rpm -q tuned tuned-0.2.19-9.el6.noarch Test #6: now with /dev/cpu_dma_latency set to 0 (via latency-performance profile) and intel_idle.max_cstate=0. The cmdline overrides /dev/cpu_dma_latency. # tuned-adm profile latency-performance pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.01 2.32 2.67 99.99 0.00 0.00 0.00 0.00 Test #7: no cmdline options + /dev/cpu_dma_latency via latency-performance profile. # tuned-adm profile latency-performance pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 100.00 2.93 2.67 0.00 0.00 0.00 0.00 0.00 |
cpu_dma_latency를 이용하여 C-State를 관리한 경우입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# /usr/libexec/tuned/pmqos-static.py cpu_dma_latency=200 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.04 2.19 2.67 0.04 0.26 99.66 0.91 91.91 Set it to anything in between 20 and 199, and you get into C3: # /usr/libexec/tuned/pmqos-static.py cpu_dma_latency=199 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.03 2.28 2.67 0.03 99.94 0.00 89.65 0.00 Set it to anything in between 1 and 19, and you get into C1: # /usr/libexec/tuned/pmqos-static.py cpu_dma_latency=19 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 0.02 2.18 2.67 99.98 0.00 0.00 0.00 0.00 Set it to 0 and you get into C0. This is what latency-performance profile does. # /usr/libexec/tuned/pmqos-static.py cpu_dma_latency=0 pk cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 100.00 2.93 2.67 0.00 0.00 0.00 0.00 0.00 |