짧은 대기 시간 작업을 위해 RHEL 9 for Real Time 최적화
Red Hat Enterprise Linux에서 RHEL for Real Time 커널 최적화
초록
보다 포괄적 수용을 위한 오픈 소스 용어 교체
Red Hat은 코드, 문서 및 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 먼저 마스터(master), 슬레이브(slave), 블랙리스트(blacklist), 화이트리스트(whitelist) 등 네 가지 용어를 교체하고 있습니다. 이러한 변경 작업은 작업 범위가 크므로 향후 여러 릴리스에 걸쳐 점차 구현할 예정입니다. 자세한 내용은 CTO Chris Wright의 메시지를 참조하십시오.
Red Hat 문서에 관한 피드백 제공
문서 개선을 위한 의견에 감사드립니다. 어떻게 개선할 수 있는지 알려주십시오.
특정 문구에 대한 의견 제출
- Multi-page HTML 형식으로 설명서를 보고 페이지가 완전히 로드된 후 오른쪽 상단 모서리에 피드백 버튼이 표시되는지 확인합니다.
- 커서를 사용하여 주석 처리할 텍스트 부분을 강조 표시합니다.
- 강조 표시된 텍스트 옆에 표시되는 피드백 추가 버튼을 클릭합니다.
- 의견을 추가하고 제출을 클릭합니다.
Jira를 통해 피드백 제출 (등록 필요)
- Jira 웹 사이트에 로그인합니다.
- 상단 탐색 모음에서 생성 을 클릭합니다.
- 요약 필드에 설명 제목을 입력합니다.
- 설명 필드에 개선을 위한 제안을 입력합니다. 문서의 관련 부분에 대한 링크를 포함합니다.
- 대화 상자 하단에서 생성 을 클릭합니다.
1장. RHEL 9의 실시간 커널 튜닝
대기 시간 또는 응답 시간은 이벤트 및 시스템 응답을 나타냅니다. 일반적으로 microseconds(microseconds)로 측정됩니다.
Linux 환경에서 실행되는 대부분의 애플리케이션의 경우 기본 성능 튜닝을 통해 대기 시간을 충분히 개선할 수 있습니다. 대기 시간이 낮고, 책임 있고 예측 가능해야 하는 업계의 경우 Red Hat은 대기 시간이 이러한 요구 사항을 충족하도록 조정할 수 있는 대체 커널을 제공합니다. RHEL for Real Time 커널은 RHEL 9와 원활한 통합을 제공하며, 고객에게 조직 내에서 대기 시간 시간을 측정, 구성 및 기록할 수 있는 기회를 제공합니다.
결정성이 매우 높은 애플리케이션의 경우 잘 조정된 시스템에서 RHEL for Real Time 커널을 사용하십시오. 커널 시스템 튜닝을 사용하면 결정성을 개선할 수 있습니다. 시작하기 전에 표준 RHEL 9 시스템의 일반 시스템 튜닝을 수행한 다음 RHEL for Real Time 커널을 배포합니다.
이러한 작업을 수행하지 않으면 RHEL 실시간 배포의 일관된 성능을 방지할 수 있습니다.
1.1. 튜닝 지침
실시간 튜닝은 반복 프로세스입니다. 몇 가지 변수를 조정하지 못하고 변경 사항이 달성 가능한 최상의지 알 수 있습니다. 며칠 또는 몇 주 동안 시스템에 가장 적합한 튜닝 구성 세트를 줄일 수 있도록 준비하십시오.
또한 항상 긴 테스트를 실행합니다. 일부 튜닝 매개변수를 변경한 다음 5분 테스트 실행을 수행하는 것은 튜닝 집합을 검증하는 것이 좋지 않습니다. 테스트 실행 길이 조정 가능한 상태로 만들고 몇 분 이상 실행하십시오. 몇 시간 동안 테스트 실행을 통해 몇 가지 다양한 튜닝 구성 세트로 좁히고 한 번에 여러 시간 또는 며칠 동안 해당 세트를 실행하여 대기 시간이 가장 높은 지연 또는 리소스 소진의 코너 케이스를 포착하십시오.
- 특정 튜닝 변경 세트가 애플리케이션의 성능에 미치는 영향을 정확하게 측정할 수 있도록 측정 메커니즘을 빌드합니다. 예를 들어, "마커가 더 원활하게 움직입니다.")는 일반적으로 잘못된 것으로, 사람마다 다릅니다. 하드 측정을 수행하고 나중에 분석을 위해 기록합니다.
- 테스트 실행 사이의 변수 튜닝에 여러 가지 변경을 하는 것은 매우 위험하지만, 이렇게 하면 테스트 결과에 영향을 미치는 튜닝을 줄일 수 있는 방법이 없습니다. 테스트 실행 간 튜닝 변경 사항은 가능한 한 작게 유지합니다.
- 또한 튜닝 시 큰 변경을 하는 것이 좋지만 증분 변경을 수행하는 것이 가장 좋습니다. 가장 낮은 우선 순위 값에서 가장 높은 우선 순위 값까지 진행하면 장기적으로 더 나은 결과를 얻을 수 있습니다.
-
사용 가능한 툴을 사용합니다.
tuna
튜닝 도구를 사용하면 스레드 및 인터럽트, 스레드 우선 순위, 애플리케이션 사용을 위해 프로세서를 격리할 수 있는 기능을 쉽게 변경할 수 있습니다.taskset
및chrt
명령행 유틸리티를 사용하면 사용 가능한 대부분의 작업을 수행할 수 있습니다. 성능 문제가 발생하는 경우ftrace
및perf
유틸리티를 사용하면 대기 시간 문제를 찾는 데 도움이 될 수 있습니다. - 애플리케이션에 값을 하드 코딩하지 않고 외부 툴을 사용하여 정책, 우선 순위 및 선호도를 변경합니다. 외부 도구를 사용하면 다양한 조합을 시도하고 논리를 단순화할 수 있습니다. 좋은 결과를 제공하는 몇 가지 설정을 찾으면 애플리케이션에 추가하거나 애플리케이션이 시작될 때 설정을 구현하도록 시작 논리를 설정할 수 있습니다.
1.2. 스레드 스케줄링 정책
Linux는 세 가지 주요 스레드 스케줄링 정책을 사용합니다.
CloudEvent_OTHER
(때로는 gRPC_NORMAL
라고도 함)이는 기본 스레드 정책이며 커널에서 제어하는 동적 우선 순위를 갖습니다. 스레드 활동에 따라 우선 순위가 변경됩니다. 이 정책이 있는 스레드는 실시간 우선 순위 0(0)으로 간주됩니다.
all_FIFO
(First in, first out)우선순위 범위가
1
~99
이고1이 가장 낮고 99
가 가장 높은 실시간 정책입니다. gRPC_FIFO
스레드는 항상 gRPC_OTHER
스레드보다 높은 우선 순위를 갖습니다(예: 우선 순위가 1인 경우, 우선 순위가1
인 스레드는 모든 CloudEvent_OTHER
스레드보다 우선 순위가 더 높습니다).10.0.0.1
_FIFO
스레드로 생성된 모든 스레드는 고정 우선 순위가 있으며 높은 우선 순위 스레드에서 차단되거나 선점될 때까지 실행됩니다.all_RR
(Round-Robin)10.0.0.1_RR
은 10.0.0.1_FIFO를 수정합니다
. 동일한 우선순위가 있는 스레드는 대망성이 있고 모든 동일한 우선 순위의 priority 10.0.0.1_RR
스레드 간에 라운드 로빈이 예약됩니다. 이 정책은 거의 사용되지 않습니다.
1.3. 로깅 매개변수 밸런싱
syslog
서버는 네트워크를 통해 프로그램에서 로그 메시지를 전달합니다. 이 경우가 작을수록 보류 중인 트랜잭션이 클 수 있습니다. 트랜잭션이 매우 크면 I/O 급증을 유발할 수 있습니다. 이를 방지하기 위해 간격을 적절히 작게 유지하십시오.
시스템 로깅 데몬 syslogd
는 다른 프로그램에서 메시지를 수집하는 데 사용됩니다. 또한 커널에서 보고한 정보를 커널 로깅 데몬인 klogd
에서 수집합니다. 일반적으로 syslogd
로그는 로컬 파일에 로그되지만 네트워크를 통해 원격 로깅 서버에 기록하도록 구성할 수도 있습니다.
절차
원격 로깅을 활성화하려면 다음을 수행합니다.
- 로그를 전송할 시스템을 구성합니다. 자세한 내용은 Red Hat Enterprise Linux에서 rsyslog를 사용한 원격 Syslogging을 참조하십시오.
syslog
출력이 로컬 파일 시스템이 아닌 서버에 기록되도록 원격 로그 서버로 로그를 보내는 각 시스템을 구성합니다. 이를 위해 각 클라이언트 시스템에서/etc/ECDHE.conf
파일을 편집합니다. 해당 파일에 정의된 각 로깅 규칙에 대해 로컬 로그 파일을 원격 로깅 서버의 주소로 바꿉니다.# Log all kernel messages to remote logging host. kern.* @my.remote.logging.server
위의 예제에서는 모든 커널 메시지를 원격 시스템에 로그하도록 클라이언트 시스템을 구성합니다.
@my.remote.logging.server
.또는
/etc/ECDHE.conf 파일에 다음 행을 추가하여 로컬에서 생성된 모든 시스템 메시지를 기록하도록
syslogd
를 구성할 수 있습니다.# Log all messages to a remote logging server: . @my.remote.logging.server
syslogd
데몬에는 생성된 네트워크 트래픽에 대한 기본 제공 속도 제한이 포함되지 않습니다. 따라서 Red Hat은 RHEL for Real Time 시스템을 사용할 때 조직에서 원격으로 기록해야 하는 로그 메시지만 사용하는 것이 좋습니다. 예를 들어 커널 경고, 인증 요청 등이 있습니다. 다른 메시지는 로컬로 기록되어야 합니다.
추가 리소스
-
syslog(3)
man page -
rsyslog.conf(5)
man page -
rsyslogd(8)
man page
1.4. 불필요한 애플리케이션을 실행하지 않도록 하여 성능 향상
실행 중인 모든 애플리케이션은 시스템 리소스를 사용합니다. 시스템에서 실행되는 불필요한 애플리케이션이 없도록 하면 성능이 크게 향상됩니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
특히 서버에서 필요하지 않은 그래픽 인터페이스를 실행하지 마십시오.
시스템이 기본적으로 GUI로 부팅되도록 구성되어 있는지 확인합니다.
# systemctl get-default
명령 출력이
graphical.target
인 경우 텍스트 모드로 부팅하도록 시스템을 구성합니다.# systemctl set-default multi-user.target
튜닝 중인 시스템에서 MTA(mail Transfer Agent) 를 적극적으로 사용하지 않는 경우 비활성화합니다. MTA가 필요한 경우 올바르게 조정되었는지 확인하거나 전용 시스템으로 이동하는 것을 고려하십시오.
자세한 내용은 MTA 문서를 참조하십시오.
중요MTA는
cron
과 같은 프로그램에서 실행하는 시스템 생성 메시지를 보내는 데 사용됩니다. 여기에는logwatch()
와 같은 로깅 함수로 생성된 보고서가 포함됩니다. 시스템의 MTA가 비활성화된 경우 이러한 메시지를 수신할 수 없습니다.mice, 키보드, 브랜젝트와 같은 약어의 장치는 대기 시간에 부정적인 영향을 미칠 수 있는 인터럽트를 보냅니다. 그래픽 인터페이스를 사용하지 않는 경우 사용되지 않는 모든 device를 제거하고 이를 비활성화합니다.
자세한 내용은 장치 설명서를 참조하십시오.
성능에 영향을 줄 수 있는 자동화된
cron
작업을 확인합니다.# crontab -l
crond
서비스 또는 불필요한cron
작업을 비활성화합니다.- 시스템에서 외부 하드웨어 공급업체가 추가한 타사 애플리케이션과 구성 요소를 확인하고 불필요한 구성 요소를 제거하십시오.
추가 리소스
-
cron(8)
매뉴얼 페이지
1.5. NUMA(Non-Uniform Memory) 액세스
taskset
유틸리티는 CPU 선호도에서만 작동하며 메모리 노드와 같은 다른 NUMA 리소스에 대한 지식이 없습니다. NUMA와 함께 프로세스 바인딩을 수행하려면 taskset
대신 numactl
명령을 사용합니다.
NUMA API에 대한 자세한 내용은 Andi Kleen의 백서 Linux용 NUMA API를 참조하십시오.
추가 리소스
-
numactl(8)
man page
1.6. debugfs가 마운트되었는지 확인
debugfs
파일 시스템은 디버깅 및 사용자가 정보를 사용할 수 있도록 특별히 설계되었습니다. RHEL 8에서 /sys/kernel/debug/
디렉토리에 자동으로 마운트됩니다.
debugfs
파일 시스템은 ftrace
및 trace-cmd
명령을 사용하여 마운트됩니다.
절차
debugfs
가 마운트되었는지 확인하려면 다음을 수행하십시오.
다음 명령을 실행합니다.
# mount | grep ^debugfs debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime,seclabel)
debugfs
가 마운트된 경우 명령은debugfs
의 마운트 지점 및 속성을 표시합니다.debugfs
가 마운트되지 않은 경우 명령은 아무것도 반환하지 않습니다.
1.7. RHEL의 InfiniBand 실시간
InfiniBand는 대역폭을 늘리고, QoS(Quality of Service)를 개선하고, 페일오버를 제공하는 데 자주 사용되는 통신 아키텍처의 유형입니다. RDP(Remote Direct Memory Access) 메커니즘을 사용하여 대기 시간을 개선할 수도 있습니다.
RHEL for Real Time에서 InfiniBand에 대한 지원은 Red Hat Enterprise Linux 9에서 제공되는 지원과 동일합니다. 자세한 내용은 InfiniBand 및 RDMA 네트워크 구성을 참조하십시오.
1.8. RoCEE 및 고성능 네트워킹 사용
RoCEE
(RDMA over Converged Enhanced Ethernet)는 이더넷 네트워크를 통해 RDMA(Remote Direct Memory Access)를 구현하는 프로토콜입니다. 이를 통해 중요한 트랜잭션을 위해 결정적이고 짧은 대기 시간 데이터 전송을 제공하는 동시에 데이터 센터에서 일관되고 고속 환경을 유지할 수 있습니다.
HPN( High Performance Networking
)은 커널에 RoCEE
인터페이스를 제공하는 공유 라이브러리 집합입니다. HPN
은 독립 네트워크 인프라를 통하지 않고 표준 이더넷 인프라를 사용하여 직접 원격 시스템 메모리에 데이터를 배치하여 CPU 오버헤드를 줄이고 인프라 비용을 줄입니다.
RHEL for Real Time에서 RoCEE
및 HPN
에 대한 지원은 RHEL 8에서 제공되는 지원과 다르지 않습니다.
추가 리소스
1.9. RHEL에서 실시간으로 컨테이너 튜닝
기본 RHEL 커널은 기본적으로 실시간 그룹 스케줄링 기능인 CONFIG_RT_GROUP_SCHED
를 활성화합니다. 그러나 실시간 커널의 경우 이 기능은 비활성화되어 있습니다.
CONFIG_RT_GROUP_SCHED
기능은 kernel-rt
패키지에 사용된 PREEMPT_RT
패치 세트와 독립적으로 개발되었으며 기본 RHEL 커널에서 실시간 프로세스에서 작동하도록 설계되었습니다. CONFIG_RT_GROUP_SCHED
기능은 대기 시간이 급증할 수 있으므로 PREEMPT_RT
지원 커널에서 비활성화됩니다. 따라서 기본 RHEL 커널에서 실행 중인 컨테이너에서 워크로드를 테스트할 때 일부 실시간 대역폭을 컨테이너에 할당하여 해당 내부에서 gRPC _FIFO 또는ECDHE
작업을 실행할 수 있습니다.
_
RR
절차
podman의
--cpu-rt-runtime
명령줄 옵션을 사용하기 전에 다음 글로벌 설정을 구성합니다.# echo 950000 > /sys/fs/cgroup/cpu,cpuacct/machine.slice/cpu.rt_runtime_us
- CPU 격리의 경우 기존 권장 사항을 사용하여 RT 워크로드에 대한 코어 집합을 별도로 설정합니다.
-
사용할 격리된 CPU 코어 목록을 사용하여
podman run --cpuset-cpus
를 실행합니다. 사용할 NUMA(Non-Uniform Memory Access) 메모리 노드를 지정합니다.
*podman run --cpuset-mems=number-of-memory-nodes
따라서 NUMA 노드 메모리 액세스가 방지됩니다.
-
컨테이너 시작 시 컨테이너에서 실행되는 실시간 워크로드에 필요한 최소 메모리 양을 확인하려면
*podman run --memory-reservation=limit
명령을 사용합니다.
추가 리소스
-
podman-run(1)
매뉴얼 페이지
2장. 실시간 RHEL 스케줄링 정책
스케줄러는 실행할 실행 가능한 스레드를 결정하는 커널 구성 요소입니다. 각 스레드에는 sched_priority
라는 연결된 스케줄링 정책 및 정적 예약 우선순위가 있습니다. 예약은 선점되므로 현재 실행 중인 스레드가 더 높은 정적 우선 순위가 있는 스레드가 실행될 준비가 되면 중지됩니다. 그런 다음 실행 중인 스레드는 정적 우선 순위에 대한 대기 목록으로
돌아갑니다.
모든 Linux 스레드에는 다음 스케줄링 정책 중 하나가 있습니다.
-
Cryostat_OTHER
또는 Cryostat_NORMAL
: 기본 정책입니다. -
Cryostat_BATCH
: Cryostat_OTHER
와 유사하지만 방향은 점진적입니다. -
Cryostat_IDLE
: is the policy with lower priority than Cryostat_OTHER
. -
Cryostat_FIFO
: 첫 번째 실시간 정책입니다. -
Cryostat_RR
: 라운드 로빈 실시간 정책입니다. -
Cryostat_DEADLINE
: 작업 기한에 따라 작업의 우선 순위를 지정하는 스케줄러 정책입니다. 가장 빠른 절대 기한을 가진 작업이 먼저 실행됩니다.
2.1. 스케줄러 정책
실시간 스레드는 표준 스레드보다 우선 순위가 높습니다. 정책에는 최소 값 1에서 최대 99까지의 스케줄링 우선순위 값이 있습니다.
다음 정책은 실시간에 중요합니다.
Cryostat_OTHER
또는Cryostat_NORMAL
정책이는 Linux 스레드의 기본 스케줄링 정책입니다. 스레드의 특성을 기반으로 시스템에 의해 변경되는 동적 우선 순위가 있습니다.
Cryostat_OTHER
스레드는 우선순위가 가장 높은 20개와 가장 낮은 우선 순위인 19 사이의 값을 갖습니다. Cryostat_OTHER 스레드의
기본 nice 값은 0입니다.Cryostat_FIFO
정책Cryostat
_FIFO
가 있는 스레드는 Cryostat_OTHER
작업보다 우선 순위가 높습니다. nice 값을 사용하는 대신, Cryostat_FIFO
는 1에서 가장 낮은 우선 순위인 가장 높은 우선 순위인 고정 우선 순위를 사용합니다. 우선 순위가 1인 A Cryostat_FIFO
스레드는 항상 먼저 a Cryostat_OTHER
스레드를 통해 예약합니다.Cryostat_RR
정책Cryo
stat_RR
정책은 Cryostat_FIFO
정책과 유사합니다. 우선순위가 동일한 스레드는 라운드 로빈 방식으로 예약됩니다.Cryostat_FIFO
및Cryostat_RR
스레드는 다음 이벤트 중 하나가 발생할 때까지 실행됩니다.- 스레드가 잠기거나 이벤트를 기다립니다.
우선순위가 높은 실시간 스레드를 실행할 준비가 되었습니다.
위의 이벤트 중 하나가 발생하지 않는 한 스레드는 지정된 프로세서에서 무기한 실행되지만 우선순위가 낮은 스레드는 실행 대기 중인 큐에 남아 있습니다. 이로 인해 시스템 서비스 스레드가 상주하고 스왑 아웃되지 않고 파일 시스템 데이터 플러시에 실패할 수 있습니다.
Cryostat_DEADLINE
정책Cryo
stat_DEADLINE
정책은 타이밍 요구 사항을 지정합니다. 작업의 데드라인에 따라 각 작업을 예약합니다. 먼저 데드라인(EDF) 일정이 가장 빠른 작업이 먼저 실행됩니다.커널을 사용하려면
runtime Cryostatdeadline Cryostatperiod
가 true여야 합니다. 필수 옵션 간의 관계는runtime Cryostatdeadline Cryostatperiod
입니다.
2.2. Cryostat_DEADLINE 정책에 대한 매개변수
각 Cryostat_DEADLINE
작업은 마침표
,런타임
및 데드라인
매개 변수로 지정됩니다. 이러한 매개변수의 값은 나노초의 정수입니다.
표 2.1. Cryostat_DEADLINE 매개변수
매개변수 | 설명 |
---|---|
|
예를 들어, 비디오 처리 작업에 처리할 초당 60 프레임이 있는 경우 16밀리초마다 서비스에 대해 새 프레임이 큐에 추가됩니다. 따라서 |
|
예를 들어 비디오 처리 도구가 이미지를 처리하는 데 5밀리초인 잘못된 경우 5밀리초를 사용할 수 있는 경우 |
|
예를 들어 작업이 10밀리초 내에 처리된 프레임을 제공해야 하는 경우 |
3장. 영구 커널 튜닝 매개변수 설정
시스템에서 작동하는 튜닝 구성을 결정한 경우 재부팅 시 변경 사항을 영구적으로 변경할 수 있습니다.
기본적으로 편집된 커널 튜닝 매개변수는 시스템이 재부팅되거나 매개 변수가 명시적으로 변경될 때까지만 적용됩니다. 이 방법은 초기 튜닝 구성을 설정하는 데 유용합니다. 또한 보안 메커니즘을 제공합니다. 편집된 매개변수로 인해 시스템이 잘못 작동하면 시스템을 재부팅하면 매개 변수가 이전 구성으로 반환됩니다.
3.1. 영구 커널 튜닝 매개변수 변경
/etc/sysctl.conf
파일에 매개변수를 추가하여 커널 튜닝 매개변수를 영구적으로 변경할 수 있습니다.
이 절차에서는 현재 세션의 커널 튜닝 매개변수를 변경하지 않습니다. /etc/sysctl.conf
에 입력한 변경 사항은 향후 세션에만 영향을 미칩니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
-
텍스트 편집기에서
/etc/sysctl.conf
를 엽니다. 매개변수의 값을 사용하여 새 항목을 파일에 삽입합니다.
/proc/sys/
경로를 제거하고 나머지 슬래시(/
)를 마침표(.
.)로 변경하고 매개 변수 값을 포함하여 매개변수 이름을 수정합니다.예를 들어
echo 0 > /proc/sys/kernel/hung_task_panic
명령을 실행하려면 다음을/etc/sysctl.conf
에 입력합니다.# Enable gettimeofday(2) kernel.hung_task_panic = 0
- 파일을 저장한 후 닫습니다.
- 변경 사항을 적용하려면 시스템을 재부팅합니다.
검증
구성을 확인하려면 다음을 수행합니다.
# cat /proc/sys/kernel/hung_task_panic 0
4장. 애플리케이션 튜닝 및 배포
다음 섹션에서는 실시간 애플리케이션용 RHEL 개선 및 개발에 대해 설명합니다.
일반적으로 POSIX
정의 API(애플리케이션 프로그래밍 인터페이스)를 사용하십시오. RHEL for Real Time은 POSIX
표준을 준수합니다. RHEL for Real Time 커널의 대기 시간 감소도 POSIX
를 기반으로 합니다.
4.1. 실시간 애플리케이션의 신호 처리
기존 UNIX
및 POSIX
신호는 특히 오류 처리를 위해 사용되지만 실시간 애플리케이션에서 이벤트 전달 메커니즘으로 적합하지 않습니다. 이는 현재 Linux 커널 신호 처리 코드가 매우 복잡하기 때문에 주로 레거시 동작과 지원되는 많은 API로 인해 발생합니다. 이러한 복잡성은 신호를 전달할 때 걸리는 코드 경로가 항상 최적의 것은 아니며 애플리케이션에서 긴 대기 시간을 경험할 수 있음을 의미합니다.
UNIX 신호의 원래 어려움은 실행의 서로 다른 "스레드" 사이에 여러 개의 제어 스레드 (프로세스)에 있습니다. 신호는 운영 체제 인터럽트와 동일하게 작동합니다. 즉, 신호가 애플리케이션에 전달되면 애플리케이션의 컨텍스트가 저장되고 이전에 등록된 신호 처리기 실행을 시작합니다. 신호 처리기가 완료되면 애플리케이션이 신호가 전달된 시점의 실행으로 돌아갑니다. 이것은 실제로 복잡해질 수 있습니다.
신호는 실시간 애플리케이션에서 신뢰할 수 없을 만큼 결정적이지 않습니다. 더 나은 옵션은 POSIX 스레드(pthreads)를 사용하여 워크로드를 배포하고 다양한 구성 요소 간에 통신하는 것입니다. pthreads 메커니즘, 조건 변수 및 장벽을 사용하여 스레드 그룹을 조정할 수 있습니다. 이러한 비교적 새로운 구성을 통한 코드 경로는 신호의 기존 처리 코드보다 훨씬 더 명확합니다.
추가 리소스
4.2. 스레드 동기화
sched_yield
명령은 더 낮은 우선 순위 스레드를 실행할 기회를 허용할 수 있는 동기화 메커니즘입니다. 이러한 유형의 요청은 잘못 작성된 애플리케이션 내에서 발행된 경우 오류가 발생하기 쉽습니다.
우선 순위가 높은 스레드는 sched_yield()
를 호출하여 다른 스레드가 실행될 기회를 허용할 수 있습니다. 호출 프로세스가 해당 우선 순위에서 실행되는 프로세스 대기열의 tail으로 이동합니다. 동일한 우선 순위에서 다른 프로세스가 실행되지 않는 경우 호출 프로세스가 계속 실행됩니다. 해당 프로세스의 우선 순위가 높은 경우 사용 중인 루프를 만들어 머신을 사용할 수 없게 될 수 있습니다.
CloudEvent _DEADLINE
작업이 sched_yield()
를 호출하면 구성된 CPU를 제공하며 나머지 런타임은 다음 기간까지 즉시 제한됩니다. sched_yield()
동작을 사용하면 다음 기간이 시작될 때 작업을 시작할 수 있습니다.
스케줄러는 실제로 실행을 기다리는 다른 스레드가 있는 시기를 더 잘 확인할 수 있습니다. 모든 실시간 작업에 sched_yield()
를 사용하지 않도록 합니다.
절차
sched_yield()
함수를 호출하려면 다음 코드를 실행합니다.for(;;) { do_the_computation(); /* * Notify the scheduler the end of the computation * This syscall will block until the next replenishment */ sched_yield(); }
10.0.0.1
_DEADLINE
작업은 다음 기간(다음 루프 시작)까지 충돌 기반 검색(CBS) 알고리즘에 의해 제한됩니다.
추가 리소스
-
pthread.h(P)
매뉴얼 페이지 -
sched_yield(2)
man page -
sched_yield(3p)
man page
4.3. 실시간 스케줄러 우선순위
systemd
명령을 사용하여 부팅 프로세스 중에 시작된 서비스의 실시간 우선 순위를 설정할 수 있습니다. 이 내용은 부팅 시 서비스의 우선 순위를 변경하는 데 설명되어 있습니다.
해당 프로세스에서 지정된 예에서 일부 커널 스레드는 매우 높은 우선 순위를 지정할 수 있습니다. 이를 통해 기본 우선순위는 RTSJ( Real Time Specification for Java
)의 요구 사항과 원활하게 통합될 수 있습니다. RTSJ
에는 10에서 89까지 다양한 우선순위가 필요합니다.
RTSJ가 사용되지 않는 배포의 경우 애플리케이션에서 사용할 수 있는 90 미만의 스케줄링 우선순위가 광범위한 것입니다. 필수 시스템 서비스가 실행되지 않도록 할 수 있으므로 우선 순위 49를 초과하는 애플리케이션 스레드를 예약할 때는 시스템 서비스가 실행되지 않도록 할 수 있습니다. 이로 인해 차단된 네트워크 트래픽, 차단된 가상 메모리 페이징 및 파일 시스템 저널링 차단으로 인한 데이터 손상 등 예기치 않은 동작이 발생할 수 있습니다.
애플리케이션 스레드가 우선 순위 89 위에 예약된 경우 스레드가 매우 짧은 코드 경로만 실행해야 합니다. 그러지 않으면 RHEL for Real Time 커널의 짧은 대기 시간이 부족해질 수 있습니다.
권한이 없는 사용자의 실시간 우선 순위 설정
기본적으로 root 사용자만 우선 순위 및 스케줄링 정보를 변경할 수 있습니다. 권한이 없는 사용자에게 이러한 설정을 조정할 수 있는 기능을 부여하려면 가장 좋은 방법은 권한이 없는 사용자를 실시간
그룹에 추가하는 것입니다.
/etc/security/limits.conf
파일을 편집하여 사용자 권한을 변경할 수도 있습니다. 그러나 이로 인해 중복되고 일반 사용자에게 시스템을 사용할 수 없게 될 수 있습니다. 이 파일을 편집하려면 변경하기 전에 주의하고 항상 복사본을 만듭니다.
4.4. 동적 라이브러리 로드
실시간 애플리케이션을 개발할 때 프로그램 실행 중에 결정적이지 않은 대기 시간을 방지하기 위해 시작시 기호를 해결하는 것이 좋습니다. 시작 시 기호를 해결하면 프로그램 초기화 속도가 느려질 수 있습니다.
동적 링커/로 LD_BIND_NOW
변수를 ld.so
로 설정하여 애플리케이션 시작 시 동적 라이브러리가 로드되도록 지시할 수 있습니다.
예를 들어 다음 쉘 스크립트는 값이 1인 LD_BIND_NOW
변수를 내보낸 다음 스케줄러 정책 FIFO 및 우선 순위 1
을 사용하여 프로그램을 실행합니다.
#!/bin/sh LD_BIND_NOW=1 export LD_BIND_NOW chrt --fifo 1 _/opt/myapp/myapp-server &_
추가 리소스
-
ld.so(8)
man page
5장. 시스템 튜닝을 위한 BIOS 매개변수 설정
BIOS는 시스템 작동에 중요한 역할을 합니다. BIOS 매개변수를 올바르게 구성하면 시스템 성능을 크게 향상시킬 수 있습니다.
모든 시스템 및 BIOS 공급 업체는 다른 용어 및 탐색 방법을 사용합니다. BIOS 설정에 대한 자세한 내용은 BIOS 설명서를 참조하거나 BIOS 공급 업체에 문의하십시오.
5.1. 전원 관리 비활성화로 응답 시간 개선
BIOS 전원 관리 옵션은 시스템 클럭 빈도를 변경하거나 CPU를 다양한 수면 상태에 배치하여 전원을 저장하는 데 도움이 됩니다. 이러한 작업은 시스템이 외부 이벤트에 얼마나 빨리 응답하는지에 영향을 미칠 수 있습니다.
응답 시간을 개선하기 위해 BIOS에서 모든 전원 관리 옵션을 비활성화합니다.
5.2. 오류 감지 및 수정 장치를 비활성화하여 응답 시간 개선
EDAC(Error Detection and Correction) 장치는 ECC(Error Correcting Code) 메모리에서 신호된 오류를 탐지하고 수정하는 장치입니다. 일반적으로 EDAC 옵션 범위는 ECC가 없는 경우 모든 메모리 노드의 주기적으로 검사에서 오류를 검사합니다. EDAC 수준이 높을수록 BIOS에서 사용하는 시간이 늘어납니다. 이로 인해 중요한 이벤트 기한이 누락될 수 있습니다.
응답 시간을 개선하기 위해 EDAC를 끄십시오. 이 작업을 수행할 수 없는 경우 EDAC를 가장 낮은 기능 수준으로 구성합니다.
5.3. 시스템 관리 Interrupts를 구성하여 응답 시간 개선
SMI(System Management Interrupts)는 시스템이 올바르게 작동하는지 확인하기 위한 하드웨어 공급업체입니다. BIOS 코드는 일반적으로 SMI 인터럽트를 서비스합니다. SMI는 일반적으로 열 관리, 원격 콘솔 관리(IPMI), EDAC 점검 및 기타 다양한 하우스키핑 작업에 사용됩니다.
BIOS에 SMI 옵션이 포함되어 있는 경우 공급 업체 및 관련 문서를 확인하여 비활성화가 안전한 정도를 확인합니다.
SMI를 완전히 비활성화할 수는 있지만 Red Hat은 이 작업을 수행하지 않는 것이 좋습니다. SMI를 생성하고 서비스하는 시스템의 기능을 제거하면 하드웨어 장애가 발생할 수 있습니다.
6장. 하드웨어 및 펌웨어 대기 시간 테스트 실행 및 해석
RHEL Real Time 커널을 사용하여 hwlatdetect
프로그램을 실행하여 잠재적 하드웨어 플랫폼이 실시간 작업에 적합한지 테스트하고 확인할 수 있습니다.
사전 요구 사항
-
RHEL-RT
(RHEL for Real Time) 및rt-tests
패키지가 설치되어 있는지 확인합니다. 짧은 대기 시간 작업에 필요한 튜닝 단계는 벤더 설명서를 확인하십시오.
공급 업체 문서는 시스템을 SMM(System Management Mode)으로 전환하는 SMI(System Management Interrupts)를 줄이거나 제거하는 지침을 제공할 수 있습니다. 시스템은 SMM에 있지만 운영 체제 코드가 아닌 펌웨어를 실행합니다. 즉, SMM에서 만료되는 타이머는 시스템이 다시 정상 작동으로 전환될 때까지 기다립니다. 이는 SMI를 Linux에서 차단할 수 없기 때문에 설명되지 않은 대기 시간이 발생할 수 있으며, 실제로 SMI를 도입한 유일한 표시는 공급 업체별 성능 카운터 레지스터에서 확인할 수 있습니다.
주의Red Hat은 심각한 하드웨어 장애가 발생할 수 있으므로 SMI를 완전히 비활성화하지 않는 것이 좋습니다.
6.1. 하드웨어 및 펌웨어 대기 시간 테스트 실행
하드웨어 아키텍처 또는 BIOS/EFI 펌웨어가 도입한 대기 시간을 찾고 있기 때문에 hwlatdetect
프로그램을 실행하는 동안 시스템에서 부하를 실행할 필요가 없습니다. hwlatdetect
의 기본값은 초당 0.5초 동안 폴링하고 연속 호출 간에 10마이크로초보다 큰 간격을 보고하여 시간을 가져오는 것입니다. hwlatdetect
는 시스템에서 가능한 최대 대기 시간을 반환합니다.
따라서 최대 대기 시간 값이 10us 미만이고 hwlatdetect
가 간격 중 하나를 20us로 보고하는 애플리케이션이 있는 경우 시스템은 20us의 대기 시간만 보장할 수 있습니다.
시스템이 애플리케이션의 대기 시간 요구 사항을 충족하지 못하는 것으로 표시되면 BIOS 설정을 변경하거나 시스템 공급 업체와 협력하여 애플리케이션의 대기 시간 요구 사항을 충족하는 새 펌웨어를 가져오십시오.
사전 요구 사항
-
RHEL-RT
및rt-tests
패키지가 설치되어 있는지 확인합니다.
절차
테스트 기간을 초 단위로 지정하여
hwlatdetect
를 실행합니다.hwlatdetect
는 클럭 소스를 폴링하고 설명되지 않은 격차를 찾아 하드웨어 및 펌웨어의 대기 시간을 찾습니다.# hwlatdetect --duration=60s hwlatdetect: test duration 60 seconds detector: tracer parameters: Latency threshold: 10us Sample window: 1000000us Sample width: 500000us Non-sampling period: 500000us Output File: None Starting test test finished Max Latency: Below threshold Samples recorded: 0 Samples exceeding threshold: 0
추가 리소스
-
hwlatdetect
매뉴얼 페이지. - 하드웨어 및 펌웨어 대기 시간 테스트 해석
6.2. 하드웨어 및 펌웨어 대기 시간 테스트 결과 해석
하드웨어 대기 시간 탐지기(hwlatdetect
)는 추적기 메커니즘을 사용하여 하드웨어 아키텍처 또는 BIOS/EFI 펌웨어가 도입한 대기 시간을 감지합니다. hwlatdetect
에서 측정한 대기 시간을 확인하여 RHEL for Real Time 커널을 지원하는 데 잠재적인 하드웨어가 적합한지 확인할 수 있습니다.
예
예제 결과는 펌웨어에서 시스템 중단을 최소화하도록 조정된 시스템을 나타냅니다. 이 경우
hwlatdetect
출력은 다음과 같습니다.# hwlatdetect --duration=60s hwlatdetect: test duration 60 seconds detector: tracer parameters: Latency threshold: 10us Sample window: 1000000us Sample width: 500000us Non-sampling period: 500000us Output File: None Starting test test finished Max Latency: Below threshold Samples recorded: 0 Samples exceeding threshold: 0
예제 결과는 펌웨어에서 시스템 중단을 최소화하도록 조정할 수 없는 시스템을 나타냅니다. 이 경우
hwlatdetect
출력은 다음과 같습니다.# hwlatdetect --duration=10s hwlatdetect: test duration 10 seconds detector: tracer parameters: Latency threshold: 10us Sample window: 1000000us Sample width: 500000us Non-sampling period: 500000us Output File: None Starting test test finished Max Latency: 18us Samples recorded: 10 Samples exceeding threshold: 10 SMIs during run: 0 ts: 1519674281.220664736, inner:17, outer:15 ts: 1519674282.721666674, inner:18, outer:17 ts: 1519674283.722667966, inner:16, outer:17 ts: 1519674284.723669259, inner:17, outer:18 ts: 1519674285.724670551, inner:16, outer:17 ts: 1519674286.725671843, inner:17, outer:17 ts: 1519674287.726673136, inner:17, outer:16 ts: 1519674288.727674428, inner:16, outer:18 ts: 1519674289.728675721, inner:17, outer:17 ts: 1519674290.729677013, inner:18, outer:17----
출력은 시스템
클럭 소스
의 연속 읽기 중에 15-18 us 범위에 표시되는 10 지연이 있음을 보여줍니다.참고이전 버전에서는
ftrace
tracer 대신 kernel 모듈을 사용했습니다.
결과 이해
테스트 메서드, 매개변수 및 결과에 대한 표에는 hwlatdetect
유틸리티에서 감지한 매개변수 및 대기 시간 값이 나열됩니다.
표 6.1. 메서드, 매개변수 및 결과 테스트
매개변수 | 현재의 | 설명 |
---|---|---|
|
| 테스트 기간(초) |
|
|
|
| ||
|
| 허용되는 최대 대기 시간 |
|
| 1초 |
|
| 0.05초 |
|
| 0.05초 |
|
| 출력이 저장되는 파일입니다. |
| ||
|
|
|
|
| 테스트에서 기록된 샘플 수입니다. |
|
|
대기 시간이 대기 시간이 |
|
| 테스트 실행 중에 발생한 SMI(System Management Interrupts) 수입니다. |
내부 및 외부에 대해 hwlatdetect
유틸리티에서 출력한 값은 최대 대기 시간입니다. 이는 현재 시스템 클럭 소스의 연속 읽기(일반적으로 TSC 또는 TSC 레지스터이지만 HPET 또는 ACPI 전원 관리 클럭)과 하드웨어 firmware 조합에 의해 도입된 연속 읽기 간의 지연 사이에 해당합니다.
적합한 hardware-firmware 조합을 찾은 후 다음 단계는 로드 중에 시스템의 실시간 성능을 테스트하는 것입니다.
7장. 시스템 대기 시간 테스트 실행 및 해석
RHEL for Real Time은 로드 중인 시스템 실시간 성능을 테스트하는 rteval
유틸리티를 제공합니다.
7.1. 사전 요구 사항
-
RHEL for Real Time
패키지 그룹이 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
7.2. 시스템 대기 시간 테스트 실행
rteval
유틸리티를 실행하여 부하에서 시스템 실시간 성능을 테스트할 수 있습니다.
사전 요구 사항
-
RHEL for Real Time
패키지 그룹이 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
절차
rteval
유틸리티를 실행합니다.# rteval
rteval
유틸리티는 시스템 로드가 많은 system load of3-4_OTHER
작업을 시작합니다. 그런 다음 각 온라인 CPU에 대한 실시간 응답을 측정합니다. 로드는 루프의 Linux 커널 트리와hackbench
합성 벤치마크의 병렬 구성 요소입니다.목표는 시스템을 각 코어에 항상 스케줄링할 작업이 있는 상태로 가져오는 것입니다. 이 작업은 메모리 할당/무료, 디스크 I/O, 전산 작업, 메모리 복사본 등과 같은 다양한 작업을 수행합니다.
로드가 시작되면 R
teval
은cyclictest
측정 프로그램을 시작합니다. 이 프로그램은 각 온라인 코어에서 skopeo_FIFO
실시간 스레드를 시작합니다. 그런 다음 실시간 스케줄링 응답 시간을 측정합니다.각 측정 스레드는 타임스탬프를 사용하여 간격 동안 유휴 상태인 다음, 다시 시작한 후 다른 타임 스탬프를 사용합니다. 측정된 대기 시간은
t1 - (t0 + i)
입니다. 이는 실제 워킹 시간t1
과 첫 번째 타임스탬프t0
의 발생 시간 차이 및 절전 간격i
입니다.rteval
실행 세부 정보는 시스템의 부팅 로그와 함께 XML 파일에 작성됩니다. 이 보고서는 화면에 표시되고 압축된 파일에 저장됩니다.파일 이름은
rteval- <date>-N -tar.bz2
형식으로 되어 있습니다. 여기서 <date
>는 보고서가 생성된 날짜이며N
th run on <date
>의 카운터입니다.
다음은 R teval
보고서의 예입니다.
System: Statistics: Samples: 1440463955 Mean: 4.40624790712us Median: 0.0us Mode: 4us Range: 54us Min: 2us Max: 56us Mean Absolute Dev: 1.0776661507us Std.dev: 1.81821060672us CPU core 0 Priority: 95 Statistics: Samples: 36011847 Mean: 5.46434910711us Median: 4us Mode: 4us Range: 38us Min: 2us Max: 40us Mean Absolute Dev: 2.13785341159us Std.dev: 3.50155558554us
보고서에는 시스템 하드웨어에 대한 세부 정보, 실행 기간, 사용된 옵션, 타이밍 결과(cpu 및 시스템 전체)가 포함됩니다.
생성된 파일에서 rteval
보고서를 다시 생성하려면 다음을 실행합니다.
# rteval --summarize rteval-<date>-N.tar.bz2
8장. RHEL for Real Time에서 CPU 선호도 설정
시스템의 모든 스레드 및 인터럽트 소스에는 프로세서 선호도 속성이 있습니다. 운영 체제 스케줄러는 이 정보를 사용하여 CPU에서 실행할 스레드와 인터럽트를 결정합니다. 효율적인 정책 및 우선 순위 설정과 함께 프로세서 선호도를 설정하면 최대한의 성능을 얻을 수 있습니다. 애플리케이션은 항상 리소스, 특히 CPU 시간을 다른 프로세스와 경쟁합니다. 애플리케이션에 따라 관련 스레드는 종종 동일한 코어에서 실행됩니다. 또는 하나의 코어에 하나의 애플리케이션 스레드를 할당할 수 있습니다.
멀티 태스킹을 수행하는 시스템은 본질적으로 결정성이 더 쉽습니다. 우선순위가 높은 애플리케이션도 더 낮은 우선 순위 애플리케이션이 코드의 중요한 섹션에 있는 동안 실행을 지연할 수 있습니다. 낮은 우선 순위 애플리케이션이 중요 섹션을 종료한 후 커널은 낮은 우선 순위 애플리케이션을 안전하게 선점하고 프로세서에서 높은 우선 순위 애플리케이션을 예약합니다. 또한 캐시 무효화로 인해 한 CPU에서 다른 CPU로 프로세스를 마이그레이션하는 것은 비용이 많이 발생할 수 있습니다. RHEL for Real Time에는 이러한 문제 중 일부를 해결하고 대기 시간을 보다 효과적으로 제어할 수 있는 도구가 포함되어 있습니다.
선호도는 비트 마스크로 표시되며, 마스크의 각 비트는 CPU 코어를 나타냅니다. 비트가 1로 설정된 경우 스레드 또는 인터럽트는 해당 코어에서 실행됩니다. 0이면 스레드 또는 인터럽트가 코어에서 실행되지 않습니다. 선호도 비트 마스크의 기본값은 모두이므로 시스템의 모든 코어에서 스레드 또는 인터럽트가 실행될 수 있습니다.
기본적으로 프로세스는 모든 CPU에서 실행할 수 있습니다. 그러나 프로세스의 선호도를 변경하면 사전 결정된 CPU 세트에서 실행할 프로세스를 정의할 수 있습니다. 하위 프로세스는 상위 프로세스의 CPU 문제를 상속합니다.
다음과 같은 일반적인 선호도 설정을 설정하면 가능한 최대 성능을 얻을 수 있습니다.
- 모든 시스템 프로세스에 단일 CPU 코어를 사용하고 나머지 코어에서 실행되도록 애플리케이션을 설정합니다.
-
동일한 CPU에서 스레드 애플리케이션 및 네트워크
softirq
또는 드라이버 스레드와 같은 특정 커널 스레드 구성. - 각 CPU에서 producer-consumer 스레드를 페어링합니다. 생산자와 소비자는 생산자가 데이터를 버퍼에 삽입하고 소비자는 버퍼에서 데이터를 제거하는 두 가지 스레드 클래스입니다.
실시간 시스템에서 효과 튜닝을 위한 일반적인 좋은 방법은 애플리케이션을 실행하는 데 필요한 코어 수를 확인한 다음 해당 코어를 분리하는 것입니다. Tuna 툴 또는 쉘 스크립트를 사용하여 taskset
명령과 같은 비트 마스크 값을 수정할 수 있습니다. taskset
명령은 프로세스의 선호도를 변경하고 /proc/
파일 시스템 항목을 수정하면 인터럽트의 선호도가 변경됩니다.
8.1. taskset
명령을 사용하여 프로세서 선호도 튜닝
실시간으로 taskset
명령은 실행 중인 프로세스의 CPU 선호도를 설정하거나 검색하는 데 도움이 됩니다. taskset
명령은 -p
및 -c
옵션을 사용합니다. -p
또는 --pid
옵션은 기존 프로세스를 작동하며 새 작업을 시작하지 않습니다. -c
또는 --cpu-list
는 비트마스크 대신 숫자 프로세서 목록을 지정합니다. 이 목록에는 둘 이상의 항목을 쉼표로 구분하여 포함할 수 있으며 다양한 프로세서가 포함될 수 있습니다. 예: 0,5,7,9-11
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
특정 프로세스의 프로세스 선호도를 확인하려면 다음을 수행합니다.
# taskset -p -c 1000 pid 1000’s current affinity list: 0,1
명령은 PID 1000을 사용하여 프로세스의 선호도를 출력합니다. 프로세스는 CPU 0 또는 CPU 1을 사용하도록 설정되어 있습니다.
(선택 사항) 프로세스를 바인딩하도록 특정 CPU를 구성하려면 다음을 수행합니다.
# taskset -p -c 1 1000 pid 1000’s current affinity list: 0,1 pid 1000’s new affinity list: 1
(선택 사항) 둘 이상의 CPU 선호도를 정의하려면 다음을 수행합니다.
# taskset -p -c 0,1 1000 pid 1000’s current affinity list: 1 pid 1000’s new affinity list: 0,1
(선택 사항) 특정 CPU에 우선 순위 수준 및 정책을 구성하려면 다음을 수행합니다.
# taskset -c 5 chrt -f 78 /bin/my-app
추가 세분성을 위해 우선순위 및 정책을 지정할 수도 있습니다. 이 예에서 명령은 CPU 5에서 10.0.0.1
_FIFO
정책 및 우선 순위 값 78에서/bin/my-app
애플리케이션을 실행합니다.
8.2. sched_setaffinity() 시스템 호출을 사용하여 프로세서 선호도 설정
real-time sched_setaffinity()
시스템 호출을 사용하여 프로세서 선호도를 설정할 수도 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
sched_setaffinity()
로 프로세서 유사성을 설정하려면 다음을 수행합니다.#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sched.h> int main(int argc, char **argv) { int i, online=0; ulong ncores = sysconf(_SC_NPROCESSORS_CONF); cpu_set_t *setp = CPU_ALLOC(ncores); ulong setsz = CPU_ALLOC_SIZE(ncores); CPU_ZERO_S(setsz, setp); if (sched_getaffinity(0, setsz, setp) == -1) { perror("sched_getaffinity(2) failed"); exit(errno); } for (i=0; i < CPU_COUNT_S(setsz, setp); i) { if (CPU_ISSET_S(i, setsz, setp)) online; } printf("%d cores configured, %d cpus allowed in affinity mask\n", ncores, online); CPU_FREE(setp); }
8.3. 높은 사용률 작업을 실행하도록 단일 CPU 격리
실시간 cpusets
메커니즘을 사용하여 gRPC _DEADLINE
작업의 CPU 및 메모리 노드 집합을 할당할 수 있습니다. 높은 CPU를 활용하는 작업을 포함하는 작업 세트에서 높은 사용률 작업을 실행하고 높은 사용률 작업을 실행하도록 CPU를 분리하고 다양한 CPU 세트에서 작은 사용률 작업을 예약하면 모든 작업이 할당된 런타임
을 충족할 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
cpuset
라는 두 디렉터리를 생성합니다.# cd /sys/fs/cgroup/cpuset/ # mkdir cluster # mkdir partition
root
cpuset
의 부하 분산을 비활성화하여cpuset
디렉터리에 두 개의 새 루트 도메인을 생성합니다.# echo 0 > cpuset.sched_load_balance
cpuset
클러스터에서 CPU 1~7에서 실행되도록 낮은 사용률 작업을 예약하고 메모리 크기를 확인하고 CPU 이름을 exclusive로 지정합니다.# cd cluster/ # echo 1-7 > cpuset.cpus # echo 0 > cpuset.mems # echo 1 > cpuset.cpu_exclusive
모든 낮은 사용률 작업을 cpuset 디렉터리로 이동합니다.
# ps -eLo lwp | while read thread; do echo $thread > tasks ; done
cpuset
이라는 파티션을 생성하고 high utilization 작업을 할당합니다.# cd ../partition/ # echo 1 > cpuset.cpu_exclusive # echo 0 > cpuset.mems # echo 0 > cpuset.cpus
쉘을 cpuset로 설정하고 데드라인 워크로드를 시작합니다.
# echo $$ > tasks # /root/d &
이 설정에서는 분할된
cpuset
디렉터리에 격리된 작업이 클러스터cpuset
디렉터리의 작업을 방해하지 않습니다. 이를 통해 모든 실시간 작업이 스케줄러 데드라인을 충족할 수 있습니다.
8.4. CPU 성능 급증 감소
일반적인 대기 시간 급증 소스는 커널 타이머 틱 처리기의 공통 잠금에 여러 CPU가 충돌하는 경우입니다. 경합을 담당하는 일반적인 잠금은 xtime_lock
이며 시간 유지 시스템과 RCU(Read-Copy-Update) 구조 잠금에서 사용됩니다. skew_tick=1
을 사용하면 CPU당 타이머 눈금을 다른 시간에 시작하도록 오프셋하고 잠재적인 잠금 충돌을 방지할 수 있습니다.
skew_tick
커널 명령줄 매개 변수는 대규모 core-count가 있는 대규모 시스템에서 대규모 시스템에 대한 대기 시간이 변동되고 대기 시간에 민감한 워크로드가 있을 수 있습니다.
사전 요구 사항
- 관리자 권한이 있습니다.
절차
grubby
를 사용하여skew_tick=1
매개변수를 활성화합니다.# grubby --update-kernel=ALL --args="skew_tick=1"
변경 사항을 적용하려면 재부팅하십시오.
# reboot
skew_tick=1
을 활성화하면 전력 소비가 크게 증가하므로 대기 시간에 민감한 실시간 워크로드를 실행하고 일관된 대기 시간이 전력 소비에 비해 중요한 고려 사항인 경우에만 skew
부팅 매개변수를 활성화해야 합니다.
검증
/proc/cmdline
파일을 표시하고 skew_tick=1
이 지정되었는지 확인합니다. /proc/cmdline
파일은 커널에 전달된 매개 변수를 표시합니다.
/proc/cmdline
파일에서 새 설정을 확인합니다.# cat /proc/cmdline
8.5. PC 카드 데몬을 비활성화하여 CPU 사용량 감소
pcscd
데몬은 병렬 통신(PC 또는 PCMCIA) 및 스마트 카드(SC) 리더에 대한 연결을 관리합니다. pcscd
는 일반적으로 우선 순위가 낮은 작업이지만 다른 데몬보다 더 많은 CPU를 사용할 수 있습니다. 따라서, 추가 배경 노이즈는 더 높은 선점 비용을 실시간 작업 및 결정론에 대한 기타 바람직하지 않은 영향을 유발할 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
pcscd
데몬의 상태를 확인합니다.# systemctl status pcscd ● pcscd.service - PC/SC Smart Card Daemon Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; vendor preset: disabled) Active: active (running) since Mon 2021-03-01 17:15:06 IST; 4s ago TriggeredBy: ● pcscd.socket Docs: man:pcscd(8) Main PID: 2504609 (pcscd) Tasks: 3 (limit: 18732) Memory: 1.1M CPU: 24ms CGroup: /system.slice/pcscd.service └─2504609 /usr/sbin/pcscd --foreground --auto-exit
Active
매개 변수는pcsd
데몬의 상태를 표시합니다.pcsd
데몬이 실행 중인 경우 이를 중지합니다.# systemctl stop pcscd Warning: Stopping pcscd.service, but it can still be activated by: pcscd.socket
시스템이 부팅될 때
pcsd
데몬이 재시작되지 않도록 시스템을 구성합니다.# systemctl disable pcscd Removed /etc/systemd/system/sockets.target.wants/pcscd.socket.
검증 단계
pcscd
데몬의 상태를 확인합니다.# systemctl status pcscd ● pcscd.service - PC/SC Smart Card Daemon Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; vendor preset: disabled) Active: inactive (dead) since Mon 2021-03-01 17:10:56 IST; 1min 22s ago TriggeredBy: ● pcscd.socket Docs: man:pcscd(8) Main PID: 4494 (code=exited, status=0/SUCCESS) CPU: 37ms
-
Active
매개변수의 값이inactive(dead)
인지 확인합니다.
9장. RHEL for Real Time에서 mlock() 시스템 호출 사용
RHEL for Real-Time 메모리 잠금(mlock())
기능을 사용하면 실시간 호출 프로세스가 주소 공간의 지정된 범위를 잠그거나 잠금 해제할 수 있습니다. 이 범위는 메모리 공간을 스왑할 때 Linux가 잠긴 메모리를 페이징하지 못하도록 합니다. 페이지 테이블 항목에 실제 페이지를 할당하면 해당 페이지에 대한 참조가 빨라집니다.
시스템 호출에는 mlock() 및 mlock()
mlockall()
의 두 가지 함수가 있습니다. 마찬가지로 munlock()
시스템 호출에는 munlock()
및 munlockall()
함수가 포함됩니다.
9.1. mlock() 및 munlock() 시스템 호출
mlock()
및 mlockall()
시스템 호출은 지정된 메모리 범위를 잠그고 이 메모리를 페이징하지 않습니다. 다음은 mlock()
시스템 호출 그룹입니다.
-
mlock()
시스템 호출: 지정된 주소 범위를 잠급니다. -
munlock()
시스템 호출: 지정된 주소 범위를 잠금 해제합니다.
mlock()
시스템 호출, 주소 범위의 페이지 잠금은 addr
에서 시작하여 len
바이트를 계속합니다. 호출이 성공적으로 반환되면 지정된 주소 범위의 일부가 포함된 모든 페이지는 나중에 잠금 해제할 때까지 메모리에 유지됩니다.
mlockall()
시스템 호출을 사용하면 매핑된 모든 페이지를 지정된 주소 범위로 잠글 수 있습니다. 메모리 잠금은 스택이 아닙니다. 여러 호출에 의해 잠긴 모든 페이지는 지정된 주소 범위 또는 단일 munlock()
시스템 호출을 사용하여 전체 영역의 잠금을 해제합니다. munlockall()
시스템 호출을 사용하면 전체 프로그램 공간을 잠금 해제할 수 있습니다.
특정 범위에 포함된 페이지의 상태는 플래그
인수의 값에 따라 다릅니다. flags
인수는 0 또는 MLOCK_ONFAULT
일 수 있습니다.
메모리 잠금은 포크를 통해 하위 프로세스에서 상속되지 않으며 프로세스가 종료될 때 자동으로 제거됩니다.
mlock()
시스템 호출을 주의해서 사용하십시오. 과도하게 사용하면 OOM(메모리 부족) 오류가 발생할 수 있습니다. 애플리케이션이 크거나 큰 데이터 도메인이 있는 경우 mlock()
호출은 시스템이 다른 작업에 메모리를 할당할 수 없는 경우 제한될 수 있습니다.
실시간 프로세스에 대한 mlockall()
호출을 사용하는 경우 충분한 스택 페이지를 예약해야 합니다.
9.2. mlock() 시스템 호출을 사용하여 페이지 잠금
실시간 mlock()
시스템 호출은 addr
매개변수를 사용하여 주소 범위의 시작을 지정하고 len
을 사용하여 주소 공간의 길이를 바이트 단위로 정의합니다. alloc_workbuf()
함수는 메모리 버퍼를 동적으로 할당하고 잠급니다. 메모리 할당은 메모리 영역을 페이지에 정렬하기 위해 posix_memalig()
함수에 의해 수행됩니다. free_workbuf()
함수는 메모리 영역을 잠금 해제합니다.
사전 요구 사항
-
큰 버퍼에
mlockall()
또는mlock()
을 사용하는 루트 권한 또는CAP_IPC_LOCK
기능이 있습니다.
절차
mlock()
시스템 호출로 페이지를 잠그려면 다음 명령을 실행합니다.#include <stdlib.h> #include <unistd.h> #include <sys/mman.h> void *alloc_workbuf(size_t size) { void ptr; int retval; // alloc memory aligned to a page, to prevent two mlock() in the same page. retval = posix_memalign(&ptr, (size_t) sysconf(_SC_PAGESIZE), size); // return NULL on failure if (retval) return NULL; // lock this buffer into RAM if (mlock(ptr, size)) { free(ptr); return NULL; } return ptr; } void free_workbuf(void *ptr, size_t size) { // unlock the address range munlock(ptr, size); // free the memory free(ptr); }
검증
실시간 mlock()
및 munlock()
호출은 성공하면 0을 반환합니다. 오류가 발생하는 경우 -1을 반환하고 오류를 나타내는 errno
를 설정합니다.
9.3. mlockall() 시스템 호출을 사용하여 매핑된 모든 페이지를 잠급니다.
mlockall()
및 munlockall()
시스템 호출을 사용하여 실시간 메모리를 잠금 및 잠금 해제하려면 플래그
인수를 0 또는 MCL_ECDHERRENT 또는
중 하나로 설정합니다. MCL_
FUTUREMCL_FUTURE
를 사용하면 mmap2(),
또는 sbrk2()
malloc3()
와 같은 향후 시스템 호출이 실패할 수 있습니다. 이로 인해 잠긴 바이트 수가 허용되는 최대를 초과할 수 있기 때문입니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
mlockall()
및munlockall()
실시간 시스템 호출을 사용하려면 다음을 수행합니다.mlockall()
시스템 호출을 사용하여 매핑된 모든 페이지를 잠급니다.#include <sys/mman.h> int mlockall (int flags)
munlockall()
시스템 호출을 사용하여 매핑된 모든 페이지를 잠금 해제합니다.#include <sys/mman.h> int munlockall (void)
추가 리소스
-
capabilities>-&
lt; 매뉴얼 페이지 -
mlock(2)
매뉴얼 페이지 -
mlock(3)
매뉴얼 페이지 -
move_pages(2)
man page -
posix_memalign(3)
man page -
posix_memalign(3p)
man page
9.4. mmap() 시스템 호출을 사용하여 파일 또는 장치를 메모리에 매핑
실시간 시스템에서 대용량 메모리 할당의 경우malloc
(메모리 할당) 방법은 mmap()
시스템 호출을 사용하여 메모리 공간을 찾습니다. flags
매개변수에서 MAP_LOCKED
를 설정하여 메모리 영역을 할당하고 잠글 수 있습니다. mmap()
은 페이지를 기준으로 메모리를 할당하므로 동일한 페이지에서 두 개의 잠금을 방지하여 이중 잠금 또는 단일 잠금 문제가 발생하지 않습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
특정 프로세스 주소 공간을 매핑하려면 다음을 수행합니다.
#include <sys/mman.h> #include <stdlib.h> void *alloc_workbuf(size_t size) { void *ptr; ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED, -1, 0); if (ptr == MAP_FAILED) return NULL; return ptr; } void free_workbuf(void *ptr, size_t size) { munmap(ptr, size); }
검증
-
mmap()
함수가 성공적으로 완료되면 매핑된 영역에 포인터를 반환합니다. error에서MAP_FAILED
값을 반환하고 오류를 나타내는errno
를 설정합니다. -
munmap()
함수가 성공적으로 완료되면0
을 반환합니다. error에서-1
을 반환하고errno
를 설정하여 오류를 나타냅니다.
추가 리소스
-
mmap(2)
매뉴얼 페이지 -
mlockall(2)
매뉴얼 페이지
9.5. mlock() 시스템 호출에 대한 매개변수
다음 표에는 mlock()
매개변수가 나열되어 있습니다.
표 9.1. mlock
매개변수
매개변수 | 설명 |
---|---|
|
잠금 또는 잠금 해제를 위한 프로세스 주소 공간을 지정합니다. NULL이 되면 커널은 메모리 내의 데이터의 페이지 정렬 정렬을 선택합니다. |
| 매핑의 길이를 지정하며 0보다 커야 합니다. |
| 파일 설명자를 지정합니다. |
|
|
|
동일한 파일을 매핑하는 다른 프로세스에 대한 매핑 가시성을 제어합니다. |
| 현재 프로세스에 매핑된 모든 페이지를 잠급니다. |
| 이후의 메모리 할당을 잠그도록 모드를 설정합니다. 이러한 페이지는 증가하는 힙 및 스택, 새로운 메모리 매핑 파일 또는 공유 메모리 영역에 필요한 새로운 페이지일 수 있습니다. |
10장. RHEL for Real Time에서 timerlat를 사용하여 예약 대기 시간 측정
rtla-timerlat
툴은 timerlat
tracer에 대한 인터페이스입니다. timerlat
추적기에서는 실시간 스레드의 가동 대기 시간을 찾습니다. timerlat
tracer는 실시간 우선 순위를 사용하여 CPU당 커널 스레드를 생성하고 이러한 스레드가 주기적으로 타이머를 설정하여 잠자기 상태로 되돌아갑니다. 발생 시 timerlat
는 운영 체제 타이머 대기 시간을 디버깅하는 데 유용한 정보를 찾아 수집합니다. timerlat
tracer는 출력을 생성하고 모든 활성화 시 다음 두 줄을 출력합니다.
-
timerlat
tracer는 타이머 인터럽트 요청(IRQs) 처리기에 표시되는 타이머 대기 시간을 주기적으로 출력합니다. 스레드 활성화 전에hardirq
컨텍스트에서 표시되는 첫 번째 출력입니다. -
두 번째 출력은 스레드의 타이머 대기 시간입니다.
ACTIVATION ID
필드에는 각각의 스레드 실행에 인터럽트 요청(IRQs) 성능이 표시됩니다.
10.1. 스케줄링 대기 시간을 측정하도록 timerlat 추적기 구성
추적 시스템의 curret_tracer
파일에 timerlat
를 추가하여 timerlat
추적기를 구성할 수 있습니다. current_tracer
파일은 일반적으로 /sys/kernel/tracing
디렉토리에 마운트됩니다. timerlat
추적기에서 인터럽트 요청(IRQ)을 측정하고 스레드 대기 시간이 100마이크로초를 초과하면 분석을 위해 추적 출력을 저장합니다.
절차
현재 추적 프로그램을 나열합니다.
# cat /sys/kernel/tracing/current_tracer nop
no operations
(nop
)는 기본 추적기입니다.추적 시스템의
current_tracer
파일에timerlat
추적기를 추가합니다.# cd /sys/kernel/tracing/ # echo timerlat > current_tracer
추적 출력을 생성합니다.
# cat trace # tracer: timerlat
검증
다음 명령을 입력하여
timerlat
가 현재 추적기로 활성화되어 있는지 확인합니다.# cat /sys/kernel/tracing/current_tracer timerlat
10.2. timerlat tracer 옵션
timerlat
tracer는 osnoise
tracer 위에 구축됩니다. 따라서 /osnoise/config
디렉터리의 옵션을 설정하여 스레드 스케줄링 대기 시간에 대한 정보를 추적 및 캡처할 수 있습니다.
Timerlat 옵션
- cpus
-
timerlat
스레드가 실행될 CPU를 설정합니다. - timerlat_period_us
-
마이크로초로
timerlat
스레드의 지속 기간을 설정합니다. - stop_tracing_us
-
irq
컨텍스트에서 타이머 대기 시간이 구성된 값보다 큰 경우 시스템 추적을 중지합니다. 0을 작성하면 이 옵션이 비활성화됩니다. - stop_tracing_total_us
- 총 노이즈가 구성된 값보다 큰 경우 시스템 추적을 중지합니다. 0을 작성하면 이 옵션이 비활성화됩니다.
- print_stack
- 인터럽트 요청(IRQ) 발생의 스택을 저장합니다. 스택은 스레드 컨텍스트 이벤트 후 IRQs 발생을 저장하거나 IRQs 처리기가 구성된 값보다 큰 값인 경우 스택은 IRQs 발생을 저장합니다.
10.3. rtla-timerlat-top를 사용하여 타이머 대기 시간 측정
rtla-timerlat-top
tracer는 timerlat
추적기에서 정기적인 출력 요약을 표시합니다. 추적기 출력은 또한 각 운영 체제의 노이즈 및 이벤트(예: osnoise
) 및 tracepoints
에 대한 정보를 제공합니다. 이 정보는 -t
옵션을 사용하여 볼 수 있습니다.
절차
타이머 대기 시간을 측정하려면 다음을 수행합니다.
# rtla timerlat top -s 30 -T 30 -t
10.4. rtla timerlat 최상위 추적기 옵션
rtla timerlat top --help
명령을 사용하면 rtla-timerlat-top tracer
옵션에 대한 도움말 사용법을 볼 수 있습니다.
timerlat-top-tracer 옵션
- -p, --period us
-
microseconds에서
timerlat
tracer 기간을 설정합니다. - -i, --irq us
- 인터럽트 요청(IRQs) 대기 시간이 마이크로초의 인수보다 크면 추적을 중지합니다.
- -t, --thread us
- 스레드 대기 시간이 마이크로초의 인수보다 크면 추적을 중지합니다.
- -t, --trace
-
중지된 추적을
timerlat_trace.txt
파일에 저장합니다. - -s, --stack us
- 스레드 대기 시간이 인수보다 큰 경우 스택 추적을 인터럽트 요청(IRQ)에 저장합니다.
11장. RHEL for Real Time에서 rtla-osnoise를 사용하여 예약 대기 시간 측정
지연 시간이 짧은 경우, 지연을 위해 허용 오차가 낮은 대량의 데이터 패킷을 처리하도록 최적화된 환경입니다. CPU를 포함한 애플리케이션에 전용 리소스를 제공하는 것은 지연 시간이 짧은 환경에서 널리 사용되는 방법입니다. 예를 들어 네트워크 기능 가상화(NFV) 애플리케이션의 고성능 네트워크 처리의 경우 단일 애플리케이션에는 작업을 지속적으로 실행하도록 CPU 전원 제한이 설정되어 있습니다.
Linux 커널에는 운영 체제 노이즈(osnoise
) 추적기용 인터페이스를 제공하는 실시간 분석(rtla
) 툴이 포함되어 있습니다. 운영 체제의 노이즈는 운영 체제 내부의 활동으로 인해 애플리케이션에서 발생하는 간섭 요인입니다. Linux 시스템의 경우 다음과 같은 문제가 발생할 수 있습니다.
- 마스크가 불가능한 인터럽트 (NMI)
- 인터럽트 요청(IRQ)
- 소프트 인터럽트 요청 (SoftIRQs)
- 기타 시스템 스레드 활동
- 마스킹할 수 없는 높은 우선 순위 시스템 관리 인터럽트(SMI)와 같은 하드웨어 관련 작업
11.1. rtla-osnoise tracer
Linux 커널에는 운영 체제 노이즈(osnoise
) 추적기용 인터페이스를 제공하는 실시간 분석(rtla
) 툴이 포함되어 있습니다. rtla-osnoise
tracer는 지정된 기간 동안 주기적으로 실행되는 스레드를 생성합니다. 마침표가 시작될 때 스레드는 인터럽트를 비활성화하고 샘플링을 시작하고 루프의 시간을 캡처합니다.At the start of a period
, the thread disables interrupts, starts sampling, and captures the time in a loop.
rtla-osnoise
tracer는 다음과 같은 기능을 제공합니다.
- CPU에서 작동하는 노이즈의 양을 측정합니다.
- CPU에서 발생하는 운영 체제 노이즈의 유형을 특성화합니다.
- 예기치 않은 결과의 근본 원인을 정의하는 데 도움이 되는 최적화된 추적 보고서를 출력합니다.
- 각 간섭 소스에 대한 간섭 카운터를 저장합니다. NMI(Non maskable interrupts), 인터럽트 요청(IRQ), 소프트웨어 인터럽트 요청(SoftIRQ) 및 툴이 이러한 간섭에 대한 입력 이벤트를 감지하면 스레드가 증가합니다.
rtla-osnoise
추적기에서는 기간 종료 시 노이즈 소스에 대한 다음 정보가 포함된 실행 보고서를 출력합니다.
- 총 노이즈 수입니다.
- 최대 노이즈 수입니다.
- 스레드에 할당된 CPU의 백분율입니다.
- 노이즈 소스에 대한 카운터입니다.
11.2. 스케줄링 대기 시간을 측정하도록 rtla-osnoise tracer 구성
추적 시스템의 curret_tracer
파일에 osnoise
를 추가하여 rtla-osnoise
tracer를 구성할 수 있습니다. current_tracer
파일은 일반적으로 /sys/kernel/tracing/
디렉토리에 마운트됩니다. rtla-osnoise
tracer는 인터럽트 요청(IRQ)을 측정하고 단일 노이즈 발생을 위해 스레드 대기 시간이 20마이크로초를 초과하면 분석을 위한 추적 출력을 저장합니다.
절차
현재 추적 프로그램을 나열합니다.
# cat /sys/kernel/tracing/current_tracer nop
no operations
(nop
)는 기본 추적기입니다.추적 시스템의
current_tracer
파일에timerlat
추적기를 추가합니다.# cd /sys/kernel/tracing/ # echo osnoise > current_tracer
추적 출력을 생성합니다.
# cat trace # tracer: osnoise
11.3. 구성을 위한 rtla-osnoise 옵션
rtla-osnoise
tracer의 구성 옵션은 /sys/kernel/tracing/
디렉터리에서 사용할 수 있습니다.
rtla-osnoise
구성 옵션
- osnoise/cpus
-
osnoise
스레드가 실행되도록 CPU를 구성합니다. - osnoise/period_us
-
osnoise
스레드 실행기간을
구성합니다. - osnoise/runtime_us
-
osnoise
스레드의 실행 기간을 구성합니다. - osnoise/stop_tracing_us
-
단일 노이즈가 구성된 값보다 큰 경우 시스템 추적을 중지합니다.
0
을 설정하면 이 옵션이 비활성화됩니다. - osnoise/stop_tracing_total_us
-
총 노이즈가 구성된 값보다 큰 경우 시스템 추적을 중지합니다.
0
을 설정하면 이 옵션이 비활성화됩니다. - tracing_thresh
-
두
time()
호출 사이의 최소 volume을 마이크로초의 노이즈로 간주하도록 설정합니다.0
으로 설정하면tracing_thresh
의 기본값인 5마이크로 설정됩니다.
11.4. rtla-osnoise 추적 지점
rtla-osnoise
에는 운영 체제 노이즈의 소스(osnoise
)를 식별하는 일련의 추적 지점이
포함되어 있습니다.
rtla-osnoise
추적 지점
- osnoise:sample_threshold
-
간격이 구성된 임계값(
tolerance_ns
)보다 크면 노이즈를 표시합니다. - osnoise:nmi_noise
- 마스크가 아닌 인터럽트 (NMI)에서 노이즈 및 노이즈 기간을 표시합니다.
- osnoise:irq_noise
- 인터럽트 요청(IRQ)에서 노이즈 및 노이즈 기간을 표시합니다.
- osnoise:softirq_noise
- 소프트 인터럽트 요청(SoftIRQ)의 노이즈 및 노이즈 기간을 표시합니다.
- osnoise:thread_noise
- 스레드에서 노이즈 및 노이즈 기간을 표시합니다.
11.5. rtla-osnoise tracer 옵션
osnoise/options
파일에는 rtla-osnoise
tracer 에
대한 설정 및 해제
설정 옵션이 포함되어 있습니다.
rtla-osnoise
옵션
- DEFAULTS
- 옵션을 기본값으로 재설정합니다.
- OSNOISE_WORKLOAD
-
osnoise
워크로드 디스패치를 중지합니다. - PANIC_ON_STOP
-
추적기가 중지되면
panic()
호출을 설정합니다. 이 옵션은vmcore
덤프 파일을 캡처합니다. - OSNOISE_PREEMPT_DISABLE
-
인터럽트 요청(IRQ) 및 하드웨어 관련 노이즈만 허용하는
osnoise
워크로드의 선점을 비활성화합니다. - OSNOISE_IRQ_DISABLE
-
osnoise
워크로드에 대해 인터럽트 요청(IRQ)을 비활성화합니다. 이 워크로드는 마스크할 수 없는 인터럽트(NMI) 및 하드웨어 관련 노이즈만 허용합니다.
11.6. rtla-osnoise-top tracer를 사용하여 운영 체제의 노이즈 측정
rtla osnoise-top
tracer는 유해 소스의 발생 카운터에 대한 정보와 함께 osnoise
추적기의 주기적인 요약을 측정하고 출력합니다.
절차
시스템 노이즈를 측정하십시오.
# rtla osnoise top -P F:1 -c 0-3 -r 900000 -d 1M -q
명령 출력은 실시간 우선 순위, 스레드를 실행하도록 할당된 CPU 및 실행 기간(마이크로초)에 대한 정보가 포함된 주기적인 요약을 표시합니다.
11.7. rtla-osnoise-top tracer 옵션
rtla osnoise top --help
명령을 사용하면 rtla-osnoise-top
tracer에 사용 가능한 옵션에서 도움말 사용량을 볼 수 있습니다.
rtla-osnoise-top
옵션
- -a, --auto us
-
자동 추적 모드를 설정합니다. 이 모드는 시스템을 디버깅하는 동안 일반적으로 사용되는 몇 가지 옵션을 설정합니다. 이것은
-s
us
-T
1
및-t
를 사용하는 것과 동일합니다. - -p, --period us
-
마이크로초로
osnoise
tracer 기간을 설정합니다. - -r, --runtime us
-
osnoise
tracer 런타임을 마이크로초로 설정합니다. - -s, --stop us
-
단일 샘플이 마이크로초의 인수보다 많은 경우 추적을 중지합니다.
-t
를 사용하면 명령에서 추적을 출력에 저장합니다. - -s, --stop-total us
-
전체 샘플이 마이크로초의 인수보다 크면 추적을 중지합니다.
-T
를 사용하면 이 명령에서 추적을 출력에 저장합니다. - -t, --threshold us
- 노이즈로 간주되는 두 시간 간의 최소 ScanSetting을 지정합니다. 기본 임계 값은 5입니다.
- -q, --quiet
- 실행 마지막에 요약만 출력합니다.
- -c, --cpus cpu-list
-
할당된
cpu-list
에서 샘플 스레드를 실행하도록osnoise
tracer를 설정합니다. - -d, --duration time[s|m|h|d]
- 실행 기간을 설정합니다.
- -D, --debug
- 디버그 정보를 출력합니다.
- -t, --trace[=file]
-
중지된 추적을
[file|osnoise_trace.txt]
파일에 저장합니다. - -e, --event sys:event
-
추적(
-t
) 세션에서 이벤트를 활성화합니다. 인수는 특정 이벤트(예:-e sched:sched_switch
) 또는-e sched
시스템 그룹과 같은 시스템 그룹의 모든 이벤트일 수 있습니다. - --filter < ;filter>
-
필터 표현식을 사용하여 이전
-e sys:event
시스템 이벤트를 필터링합니다. - --trigger <trigger>
-
이전
-e sys:event
시스템 이벤트에 대한 추적 이벤트 트리거를 활성화합니다. - -p, --priority o:prio|r:prio|f:prio|d:runtime:period
-
스케줄링 매개변수를
osnoise
tracer 스레드로 설정합니다. - -h, --help
- 도움말 메뉴를 출력합니다.
12장. 저널링으로 인한 시스템 속도 저하 최소화 또는 방지
저널이 디스크에 기록되는 순서는 도착 순서와 다를 수 있습니다. 커널 I/O 시스템에서는 저널 변경 사항을 다시 정렬하여 사용 가능한 스토리지 공간 사용을 최적화할 수 있습니다. journal 활동으로 저널을 다시 정렬하고 데이터 및 메타데이터를 커밋하여 시스템 대기 시간이 발생할 수 있습니다. 결과적으로 파일 시스템이 시스템을 느려질 수 있습니다.
XFS
는 RHEL 8에서 사용하는 기본 파일 시스템입니다. 이것은 저널링 파일 시스템입니다. ext2
라는 이전 파일 시스템에서는 저널링을 사용하지 않습니다. 조직에 특별히 저널링이 필요하지 않은 경우 ext2
파일 시스템을 고려하십시오. 많은 Red Hat의 최상의 벤치마크 결과에서 ext2
파일 시스템이 사용됩니다. 이는 초기 튜닝 권장 사항 중 하나입니다.
XFS
와 같은 저널링 파일 시스템은 파일에 마지막으로 액세스한 시간( atime
특성)을 기록합니다. 저널링 파일 시스템을 사용해야 하는 경우 시간 비활성화를
고려하십시오.
12.1. atime 비활성화
atime
특성을 비활성화하면 성능이 향상되고 파일 시스템 저널에 대한 쓰기 횟수를 제한하여 전원 사용량이 감소합니다.
절차
선택한 텍스트 편집기를 사용하여
/etc/fstab
파일을 열고 root 마운트 지점의 항목을 찾습니다./dev/mapper/rhel-root / xfs defaults…
noatime
및nodiratime
용어를 포함하도록 options 섹션을 편집합니다.noatime
옵션은 파일을 읽을 때 액세스 타임스탬프를 업데이트할 수 없으며nodiratime
옵션은 업데이트되는 디렉터리 inode 액세스 시간을 중지합니다./dev/mapper/rhel-root / xfs noatime,nodiratime…
일부 애플리케이션은 업데이트되는 시간에
의존합니다. 따라서 이 옵션은 이러한 애플리케이션이 사용되지 않는 시스템에서만 적합합니다.
또는 relatime
마운트 옵션을 사용하면 이전 액세스 시간이 현재 수정 시간보다 오래된 경우에만 액세스 시간이 업데이트되도록 할 수 있습니다.
12.2. 추가 리소스
-
mkfs.ext2(8)
man page -
mkfs.xfs(8)
man page -
mount(8)
매뉴얼 페이지
13장. 대기 시간에 민감한 워크로드에 대한 그래픽 콘솔 출력 비활성화
커널은 시작 직후 printk()
에 메시지를 전달하기 시작합니다. 커널은 메시지를 로그 파일에 전송하고 헤드리스 서버에 모니터가 연결되어 있지 않은 경우에도 그래픽 콘솔에 표시됩니다.
일부 시스템에서는 그래픽 콘솔로 전송된 출력이 파이프라인에서 stalls를 도입할 수 있습니다. 이로 인해 데이터 전송을 기다리는 동안 작업 실행이 지연될 수 있습니다. 예를 들어, teletype0
(/dev/tty0)
으로 전송된 출력으로 인해 일부 시스템에서 잠재적인 stall이 발생할 수 있습니다.
예기치 않은 stall을 방지하기 위해 다음을 통해 그래픽 콘솔에 전송된 정보를 제한하거나 비활성화할 수 있습니다.
-
tty0
정의 제거. - 콘솔 정의 순서 변경
-
대부분의
printk()
함수를 끄고ignore_loglevel
커널 매개변수를구성하지 않도록 합니다
.
그래픽 콘솔 출력을 로깅에서 비활성화하고 그래픽 콘솔에 출력하는 메시지를 제어하면 중요한 워크로드에 대한 대기 시간을 개선할 수 있습니다.
13.1. 그래픽 어댑터에 대한 그래픽 콘솔 로깅 비활성화
Teletype
(tty
) 기본 커널 콘솔을 사용하면 입력 데이터를 시스템에 전달하고 그래픽 콘솔에 대한 출력 정보를 표시하여 시스템과 상호 작용할 수 있습니다.
그래픽 콘솔을 구성하지 않고 그래픽 어댑터에 로깅하지 못하도록 합니다. 이렇게 하면 시스템에서 tty0
을 사용할 수 없으며 그래픽 콘솔에서 메시지 인쇄를 비활성화하는 데 도움이 됩니다.
그래픽 콘솔 출력을 비활성화해도 정보가 삭제되지 않습니다. 이 정보는 시스템 로그에 출력되고 journalctl
또는 dmesg
유틸리티를 사용하여 액세스할 수 있습니다.
절차
커널 구성에서
console=tty0
옵션을 제거합니다.# grubby --update-kernel=ALL --remove-args="console=tty0"
13.2. 그래픽 콘솔에 인쇄에서 메시지 비활성화
/proc/sys/kernel/printk
파일에서 필요한 로그 수준을 구성하여 그래픽 콘솔에 전송되는 출력 메시지의 양을 제어할 수 있습니다.
절차
현재 콘솔 로그 수준을 확인합니다.
$ cat /proc/sys/kernel/printk 7 4 1 7
명령은 시스템 로그 수준에 대한 현재 설정을 출력합니다. 숫자는 시스템 로거의 현재, 기본값, 최소 및 boot-default 값에 해당합니다.
/proc/sys/kernel/printk
파일에서 원하는 로그 수준을 구성합니다.$ echo “1” > /proc/sys/kernel/printk
명령은 현재 콘솔 로그 수준을 변경합니다. 예를 들어 로그 수준 1을 설정하면 경고 메시지만 출력되고 그래픽 콘솔의 다른 메시지가 표시되지 않습니다.
14장. 애플리케이션 요구 사항을 충족하기 위해 시스템 클럭 관리
NUMA 또는 SMP와 같은 다중 프로세서 시스템에는 여러 개의 하드웨어 클럭 인스턴스가 있습니다. 부팅 시간 동안 커널은 사용 가능한 클럭 소스를 검색하고 사용할 하나를 선택합니다. 성능 향상을 위해 실시간 시스템의 최소 요구사항을 충족하는 데 사용되는 클럭 소스를 변경할 수 있습니다.
14.1. 하드웨어 클럭
NUMA(Non-Uniform Memory Access) 및 SMP(Symmetric Multiprocessing)와 같은 다중 프로세서 시스템에서 발견된 여러 클럭 소스 인스턴스는 CPU 빈도 스케일링 또는 에너지 충돌 모드 입력과 같은 시스템 이벤트에 반응하는 방식으로 실시간 커널에 적합한 클럭 소스를 결정합니다.
기본 클럭 소스는 TSC(Time Stamp CloudEvent)입니다. TSC를 사용할 수 없는 경우 HPET(High Precision Event Timer)가 두 번째 최선의 옵션입니다. 그러나 모든 시스템에 HPET 시계가 있는 것은 아니며 일부 HPET 시계는 신뢰할 수 없습니다.
TSC 및 HPET가 없는 경우 다른 옵션에는 ACPI Power Management Timer(ACPI_PM), PIT(Programmable Interval Timer) 및 RTC(Real Time Clock)가 포함됩니다. 마지막 두 가지 옵션은 읽기 비용이 많이 들거나 낮은 해상도(시간 세분성)이므로 실시간 커널과 함께 사용할 수 있는 하위 선택 사항입니다.
14.2. 시스템에서 사용 가능한 클럭 소스 보기
시스템에서 사용 가능한 클럭 소스 목록은 /sys/devices/system/clocksource/clocksource0/available_clocksource
파일에 있습니다.
절차
available_clocksource
파일을 표시합니다.# cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm
이 예에서 시스템에서 사용 가능한 클럭 소스는 TSC, HPET 및 ACPI_PM입니다.
14.3. 현재 사용 중인 클럭 소스 보기
시스템에서 현재 사용되는 클럭 소스는 /sys/devices/system/clocksource/clocksource0/current_clocksource
파일에 저장됩니다.
절차
current_clocksource
파일을 표시합니다.# cat /sys/devices/system/clocksource/clocksource0/current_clocksource tsc
이 예에서 시스템의 현재 클럭 소스는 TSC입니다.
14.4. 사용할 클럭 소스를 일시적으로 변경
때때로 시계의 알려진 문제로 인해 시스템의 주요 애플리케이션에 대한 최상의 시계가 사용되지 않는 경우가 있습니다. 문제가 있는 모든 시계를 제거한 후 실시간 시스템의 최소 요구사항을 충족할 수 없는 하드웨어 시계를 사용할 수 있습니다.
중요한 애플리케이션에 대한 요구 사항은 시스템마다 다릅니다. 따라서 각 애플리케이션에 가장 적합한 시계와 결과적으로 각 시스템도 달라집니다. 일부 애플리케이션은 클럭 해상도에 따라 다르며 안정적인 나노초 수치를 제공하는 시계가 더 적합할 수 있습니다. 시계를 너무 자주 읽는 애플리케이션은 읽기 비용이 적게 드는 시계의 이점을 누릴 수 있습니다(읽음 요청과 결과 사이의 시간).
이러한 경우 재정의의 부작용을 이해하고 지정된 하드웨어 클록의 알려진 단점을 트리거하지 않는 환경을 생성할 수 있는 경우 커널에서 선택한 시계를 재정의할 수 있습니다.
커널은 사용 가능한 최상의 클럭 소스를 자동으로 선택합니다. 선택한 클럭 소스를 재정의하는 것은 의미가 잘 이해되지 않는 한 권장되지 않습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
사용 가능한 클럭 소스를 확인합니다.
# cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm
예를 들어 시스템에서 사용 가능한 클럭 소스는 TSC, HPET 및 ACPI_PM이라고 가정합니다.
/sys/devices/system/clocksource/clocksource0/current_clocksource
파일에 사용할 클럭 소스의 이름을 작성합니다.# echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource
참고변경 사항은 현재 사용 중인 클럭 소스에 적용됩니다. 시스템이 재부팅되면 기본 시계가 사용됩니다. 변경 사항을 영구적으로 만들려면 영구 커널 튜닝 매개 변수 변경 사항을 참조하십시오.
검증 단계
current_clocksource
파일을 표시하여 현재 클럭 소스가 지정된 클럭 소스인지 확인합니다.# cat /sys/devices/system/clocksource/clocksource0/current_clocksource hpet
이 예제에서는 HPET를 시스템의 현재 클럭 소스로 사용합니다.
14.5. 하드웨어 클럭 소스를 읽는 비용 비교
시스템의 시계 속도를 비교할 수 있습니다. TSC에서 읽는 것은 프로세서에서 레지스터를 읽는 것과 관련이 있습니다. HPET 시계에서 읽는 것은 메모리 영역을 읽는 것입니다. TSC에서 읽는 것이 더 빠르기 때문에 초당 수십만 개의 메시지를 타임스탬프할 때 상당한 성능 이점을 제공합니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
-
clock_timing
프로그램은 시스템에 있어야 합니다. 자세한 내용은 clock_timing 프로그램을 참조하십시오.
절차
clock_timing
프로그램이 저장되는 디렉터리로 변경합니다.# cd clock_test
시스템에서 사용 가능한 클럭 소스를 확인합니다.
# cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm
이 예에서 시스템에서 사용 가능한 클럭 소스는
TSC
,HPET
및ACPI_PM
입니다.현재 사용된 클럭 소스를 확인합니다.
# cat /sys/devices/system/clocksource/clocksource0/current_clocksource tsc
이 예에서 시스템의 현재 클럭 소스는
TSC
입니다../
clock_timing
프로그램과 함께시간
유틸리티를 실행합니다. 출력에는 클럭 소스를 10만 번 읽는 데 필요한 기간이 표시됩니다.# time ./clock_timing real 0m0.601s user 0m0.592s sys 0m0.002s
이 예제에서는 다음 매개변수를 보여줍니다.
-
Real
- 프로세스가 종료될 때까지 프로그램 호출부터 시작된 총 시간입니다.실제
에는 사용자 및 커널 시간이 포함되며 일반적으로 마지막 두 시간의 합계보다 큽니다. 이 프로세스가 우선 순위가 높은 애플리케이션 또는 하드웨어 인터럽트(IRQ)와 같은 시스템 이벤트에 의해 중단되는 경우 이 시간도실제
대기에서 계산됩니다. -
사용자
- 프로세스에서 커널 개입이 필요하지 않은 작업을 수행하는 데 소비된 시간입니다. -
sys
- 사용자 프로세스에 필요한 작업을 수행하는 동안 커널에서 보낸 시간입니다. 이러한 작업에는 파일 열기, 읽기 및 파일 또는 I/O 포트, 메모리 할당, 스레드 생성 및 네트워크 관련 활동이 포함됩니다.
-
테스트할 다음 클럭 소스의 이름을
/sys/devices/system/clocksource/clocksource0/current_clocksource
파일에 작성합니다.# echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource
이 예에서는 현재 클럭 소스가
HPET
로 변경됩니다.- 사용 가능한 모든 시계 소스에 대해 4단계와 5단계를 반복합니다.
- 사용 가능한 모든 클럭 소스에 대해 단계 4의 결과를 비교합니다.
추가 리소스
-
time(1)
매뉴얼 페이지
14.6. Opteron CPU에서 TSC 타이머 동기화
현재 AMD64 Opteron 프로세서의 현재 생성은 대규모 gettimeofday
skew에 취약할 수 있습니다. 이 스큐는 cpufreq
및 TSC( Time Stamp Forwarded)를 모두 사용할 때 발생합니다. RHEL for Real Time은 모든 프로세서가 동일한 빈도로 동시에 변경되는 것을 방지할 수 있는 방법을 제공합니다. 결과적으로 단일 프로세서의 TSC는 다른 프로세서의 TSC와 다른 속도로 증가하지 않습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
clocksource=tsc
및powernow-k8.tscsync=1
커널 옵션을 활성화합니다.# grubby --update-kernel=ALL --args="clocksource=tsc powernow-k8.tscsync=1"
이를 통해 TSC를 강제로 사용하고 동시 코어 프로세서 주파수 전환을 가능하게 합니다.
- 컴퓨터를 다시 시작합니다.
추가 리소스
-
gettimeofday(2)
매뉴얼 페이지
14.7. clock_timing 프로그램
clock_timing
프로그램은 현재 시계 소스를 10만 번 읽습니다. 시간
유틸리티와 함께 이 작업을 수행하는 데 필요한 시간을 측정합니다.
절차
clock_timing
프로그램을 생성하려면 다음을 수행합니다.
프로그램 파일용 디렉터리를 생성합니다.
$ mkdir clock_test
생성된 디렉터리로 변경합니다.
$ cd clock_test
소스 파일을 생성하고 텍스트 편집기에서 엽니다.
$ {EDITOR} clock_timing.c
파일에 다음을 입력합니다.
#include <time.h> void main() { int rc; long i; struct timespec ts; for(i=0; i<10000000; i++) { rc = clock_gettime(CLOCK_MONOTONIC, &ts); } }
- 파일을 저장하고 편집기를 종료합니다.
파일을 컴파일합니다.
$ gcc clock_timing.c -o clock_timing -lrt
clock_timing
프로그램이 준비되었으며 저장된 디렉터리에서 실행할 수 있습니다.
15장. 전원 관리 전환 제어
전원 관리 전환을 제어하여 대기 시간을 개선할 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
15.1. 절전 상태
최신 프로세서는 낮은 상태에서 더 높은 전력 절약 상태 (C-states)로 적극적으로 전환합니다. 슬프게도 높은 절전 상태에서 실행 상태로 전환하면 실시간 애플리케이션에 가장 적합한 것보다 더 많은 시간이 걸릴 수 있습니다. 이러한 전환을 방지하기 위해 애플리케이션은 PM QoS(Power Management Quality of Service) 인터페이스를 사용할 수 있습니다.
PM QoS 인터페이스를 사용하면 시스템은 idle=poll
및 processor.max_cstate=1
매개변수의 동작을 에뮬레이션할 수 있지만 전원 절약 상태를 보다 세밀하게 제어할 수 있습니다. idle=poll
은 프로세서가 유휴
상태로 전환되지 않습니다. processor.max_cstate=1
은 프로세서가 더 깊은 C 상태(energy-saving 모드)를 입력하지 못하도록 합니다.
애플리케이션에 /dev/cpu_dma_latency
파일이 열려 있으면 PM QoS 인터페이스에서 프로세서가 깊은 절전 상태를 입력하지 못하도록 하여 종료 시 예기치 않은 대기 시간이 발생합니다. 파일이 닫히면 시스템은 절전 상태로 돌아갑니다.
15.2. 전원 관리 상태 구성
전원 관리 상태를 구성하여 전원 관리 전환을 제어할 수 있습니다. 보다 구체적으로는 /dev/cpu_dma_latency
파일에 값을 작성하여 프로세스의 최대 응답 시간을 마이크로초 단위로 변경할 수 있습니다. 또는 애플리케이션 또는 스크립트에서 이 파일을 참조할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
cpu_dma_latency
파일을 생성합니다.$ touch /dev/cpu_dma_latency
텍스트 편집기에서 파일을 엽니다.
$ sudo {EDITOR} /dev/cpu_dma_latency
다음 프로그램 행을 파일에 추가합니다.
#include <errno.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> FILE *fp; void start_low_latency() { char target = '0'; fp= fopen("/dev/cpu_dma_latency", "r+"); if (fp == NULL) { fprintf(stderr, "Failed to open PM QOS file: %s", strerror(errno)); exit(errno); } fputc(target, fp); } void stop_low_latency() { if (fp == NULL) fclose(fp); } int main() { start_low_latency(); //do some latency-sensitive tasks here stop_low_latency(); return 0; }
프로그램을 컴파일합니다.
$ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}
프로그램을 실행합니다.
$ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}
16장. 인터럽트 및 사용자 프로세스를 격리하여 시스템 대기 시간 최소화
실시간 환경에서는 다양한 이벤트에 응답할 때 대기 시간을 최소화하거나 제거해야 합니다. 이를 위해 서로 다른 전용 CPU에서 인터럽트(IRQ)를 사용자 프로세스에서 분리할 수 있습니다.
16.1. 인터럽트 및 프로세스 바인딩
다른 전용 CPU의 사용자 프로세스에서 인터럽트(IRQ)를 격리하면 실시간 환경에서 대기 시간을 최소화하거나 제거할 수 있습니다.
인터럽트는 일반적으로 CPU 간에 균등하게 공유됩니다. 이렇게 하면 CPU가 새 데이터 및 명령 캐시를 작성해야 하는 경우 인터럽트 처리가 지연될 수 있습니다. 이러한 인터럽트 지연으로 인해 동일한 CPU에서 다른 처리가 실행될 수 있습니다.
시간이 중요한 인터럽트 및 프로세스를 특정 CPU(또는 CPU 범위)에 할당할 수 있습니다. 이러한 방식으로 이 인터럽트를 처리하는 코드 및 데이터 구조는 프로세서 및 명령 캐시에 있을 가능성이 높습니다. 결과적으로 전용 프로세스는 가능한 한 빨리 실행될 수 있지만 다른 모든 비시간 크리티컬 프로세스는 다른 CPU에서 실행됩니다. 이는 관련된 속도가 메모리의 제한 또는 메모리의 제한과 사용 가능한 경미한 버스 대역폭에 특히 중요할 수 있습니다. 메모리가 프로세서 캐시로 가져오기를 기다릴 경우 전체 처리 시간과 결정성에 큰 영향을 미칩니다.
실제로 최적의 성능은 전적으로 애플리케이션에 따라 다릅니다. 예를 들어 다른 회사에서 유사한 기능을 가진 애플리케이션을 튜닝하려면 완전히 다른 최적의 성능 튜닝이 필요했습니다.
- 한 회사에서는 운영 체제 기능 및 인터럽트 처리를 위해 4개의 CPU 중 2개를 분리할 때 최적의 결과를 확인했습니다. 나머지 2개의 CPU는 애플리케이션 처리를 위해 전적으로 전용이었습니다.
- 또 다른 기업은 네트워크 관련 애플리케이션 프로세스를 네트워크 장치 드라이버 인터럽트를 처리하는 단일 CPU에 바인딩할 때 최적의 결정성을 발견했습니다.
일반적으로 CPU에 프로세스를 바인딩하려면 지정된 CPU 또는 CPU 범위에 대한 CPU 마스크를 알아야 합니다. CPU 마스크는 일반적으로 사용 중인 명령에 따라 32비트 비트마스크, 10진수 또는 16진수로 표시됩니다.
표 16.1. 지정된 CPU에 대한 CPU의 예
CPU | Bitmask | 10진수 | Hexadecimal |
0 | 00000000000000000000000000000001 | 1 | 0x00000001 |
0, 1 | 00000000000000000000000000000011 | 3 | 0x00000011 |
16.2. irqbalance 데몬 비활성화
irqbalance
데몬은 기본적으로 활성화되어 있으며 주기적으로 CPU에서 인터럽트를 처리하는 방식으로 강제 처리됩니다. 그러나 실시간 배포에서는 애플리케이션이 일반적으로 특정 CPU에 바인딩되므로 irqbalance
가 필요하지 않습니다.
절차
irqbalance
의 상태를 확인합니다.# systemctl status irqbalance irqbalance.service - irqbalance daemon Loaded: loaded (/usr/lib/systemd/system/irqbalance.service; enabled) Active: active (running) …
irqbalance
가 실행 중인 경우 이를 비활성화하고 중지합니다.# systemctl disable irqbalance # systemctl stop irqbalance
검증
irqbalance
상태가 inactive인지 확인합니다.# systemctl status irqbalance
16.3. IRQ 밸런싱에서 CPU 제외
IRQ 밸런싱 서비스를 사용하여 인터럽트(IRQ) 밸런싱에서 제외할 CPU를 지정할 수 있습니다. /etc/sysconfig/irqbalance
구성 파일의 IRQBALANCE_BANNED_CPUS
매개변수는 이러한 설정을 제어합니다. 매개 변수의 값은 64비트 16진수 비트 마스크이며 마스크의 각 비트는 CPU 코어를 나타냅니다.
절차
원하는 텍스트 편집기에서
/etc/sysconfig/irqbalance
를 열고IRQBALANCE_BANNED_CPUS
라는 파일의 섹션을 찾습니다.# IRQBALANCE_BANNED_CPUS # 64 bit bitmask which allows you to indicate which cpu's should # be skipped when reblancing irqs. Cpu numbers which have their # corresponding bits set to one in this mask will not have any # irq's assigned to them on rebalance # #IRQBALANCE_BANNED_CPUS=
-
IRQBALANCE_BANNED_CPUS
변수의 주석을 제거합니다. - IRQ 균형 메커니즘에서 무시할 CPU를 지정하려면 적절한 비트마스크를 입력합니다.
- 파일을 저장한 후 닫습니다.
최대 64개의 CPU 코어가 있는 시스템을 실행하는 경우 각 16진수 그룹을 쉼표로 구분합니다. 예: IRQBALANCE_BANNED_CPUS=00000001,0000ff00
표 16.2. 예
CPU | Bitmask |
0 | 00000001 |
8 - 15 | 0000ff00 |
8 - 15, 33 | 00000001,0000ff00 |
RHEL 7.2 이상에서는 IRQBALANCE_BANNED_CPUS
가 /etc/sysconfig/irqbalance
에 설정되지 않은 경우 isolcpus
커널 매개변수를 통해 격리된 CPU 코어의 IRQ를 자동으로 방지할 수 있습니다.
16.4. 개별 IRQ에 CPU 선호도를 수동으로 할당
CPU 선호도를 할당하면 프로세스 및 스레드를 지정된 CPU 또는 CPU 범위에 바인딩 및 바인딩 해제할 수 있습니다. 이렇게 하면 캐싱 문제를 줄일 수 있습니다.
절차
/proc/interrupts
파일을 확인하여 각 장치에서 사용 중인 IRQ를 확인합니다.# cat /proc/interrupts
각 줄에는 IRQ 번호, 각 CPU에서 발생한 인터럽트 수, IRQ 유형 및 설명이 표시됩니다.
CPU0 CPU1 0: 26575949 11 IO-APIC-edge timer 1: 14 7 IO-APIC-edge i8042
특정 IRQ의
smp_affinity
항목에 CPU 마스크를 작성합니다. CPU 마스크는 16진수로 표시되어야 합니다.예를 들어 다음 명령은 CPU 0에서만 실행되도록 IRQ 번호 142에 지시합니다.
# echo 1 > /proc/irq/142/smp_affinity
변경 사항은 인터럽트가 발생했을 때만 적용됩니다.
검증 단계
- 지정된 인터럽트를 트리거할 활동을 수행합니다.
/proc/interrupts
에서 변경 사항을 확인합니다.구성된 IRQ에 대해 지정된 CPU의 인터럽트 수가 증가하고 지정된 선호도 외부의 CPU에서 구성된 IRQ의 인터럽트 수가 증가하지 않았습니다.
16.5. taskset 유틸리티를 사용하여 CPU에 프로세스 바인딩
taskset
유틸리티는 작업의 PID(프로세스 ID)를 사용하여 CPU 선호도를 보거나 설정합니다. 유틸리티를 사용하여 선택한 CPU 선호도로 명령을 실행할 수 있습니다.
선호도를 설정하려면 CPU 마스크를 10진수 또는 16진수로 가져와야 합니다. mask 인수는 수정 중인 명령 또는 PID에 적합한 CPU 코어를 지정하는 비트 마스크
입니다.
taskset의
유틸리티는 NUMA(Non-Uniform Memory Access) 시스템에서 작동하지만 사용자가 스레드를 CPU 및 가장 가까운 NUMA 메모리 노드에 바인딩하는 것을 허용하지 않습니다. 이러한 시스템에서 taskset은 기본 도구가 아니며 고급 기능에 numactl
유틸리티를 사용해야 합니다.
자세한 내용은 numactl(8)
매뉴얼 페이지를 참조하십시오.
절차
필요한 옵션 및 인수를 사용하여
작업 세트를
실행합니다.CPU 마스크 대신 -c 매개변수를 사용하여 CPU 목록을 지정할 수 있습니다. 이 예에서
my_em embeddedded_process
는 CPU 0,4,7-11에서만 실행되도록 지시하고 있습니다.# taskset -c 0,4,7-11 /usr/local/bin/my_embedded_process
이 호출은 대부분의 경우 더 편리합니다.
현재 실행되고 있지 않은 프로세스의 선호도를 설정하려면
taskset
을 사용하고 CPU 마스크와 프로세스를 지정합니다.이 예에서
my_em embeddedded_process
는 CPU 3만 사용하도록 지시합니다(CPU 마스크의 10진수 버전 사용).# taskset 8 /usr/local/bin/my_embedded_process
비트마스크에서 두 개 이상의 CPU를 지정할 수 있습니다. 이 예에서
my_em embeddedded_process
는 프로세서 4, 5, 6, 7에서 실행되도록 지시합니다(CPU 마스크의 16진수 버전 사용).# taskset 0xF0 /usr/local/bin/my_embedded_process
변경하려는 프로세스의 PID와 함께
-p
(--pid
) 옵션을 사용하여 이미 실행 중인 프로세스의 CPU 선호도를 설정할 수 있습니다. 이 예에서 PID가 7013인 프로세스는 CPU 0에서만 실행되도록 지시합니다.# taskset -p 1 7013
나열된 옵션을 결합할 수 있습니다.
추가 리소스
-
taskset(1)
man page -
numactl(8)
man page
17장. 메모리 부족 상태 관리
메모리 부족(OOM)은 스왑 공간을 포함하여 사용 가능한 모든 메모리가 할당된 컴퓨팅 상태를 나타냅니다. 일반적으로 이로 인해 시스템이 패닉 상태가 되고 예상대로 작동하지 않습니다.
다음은 시스템의 OOM 상태를 방지하기 위한 지침을 제공합니다.
17.1. 사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
17.2. 메모리 부족 값 변경
/proc/sys/vm/panic_on_oom
파일에는 OOM(Out of Memory) 동작을 제어하는 스위치인 값이 포함되어 있습니다. 파일에 1
개가 포함된 경우 커널은 OOM에 패닉 상태가 되고 예상대로 작동하지 않습니다.
기본값은 0
입니다. 이는 시스템이 OOM 상태에 있을 때 커널이 oom_killer()
함수를 호출하도록 지시합니다. 일반적으로 oom_killer()
는 불필요한 프로세스를 종료하므로 시스템이 유지될 수 있습니다.
/proc/sys/vm/panic_on_oom
의 값을 변경할 수 있습니다.
절차
/proc/sys/vm/panic_on_oom
의 현재 값을 표시합니다.# cat /proc/sys/vm/panic_on_oom 0
/proc/sys/vm/panic_on_oom
에서 값을 변경하려면 다음을 수행합니다.새 값을
/proc/sys/vm/panic_on_oom
으로 에코합니다.# echo 1 > /proc/sys/vm/panic_on_oom
OOM(OOM 1)에서 Real-Time 커널 패닉을 생성하는 것이 좋습니다. 그렇지 않으면 시스템이 OOM 상태가 되면 더 이상 결정적이지 않습니다.
검증 단계
/proc/sys/vm/panic_on_oom
값을 표시합니다.# cat /proc/sys/vm/panic_on_oom 1
- 표시된 값이 지정된 값과 일치하는지 확인합니다.
17.3. 메모리 부족 상태의 경우 종료할 프로세스 우선 순위 지정
oom_killer()
함수로 종료되는 프로세스의 우선 순위를 지정할 수 있습니다. 이렇게 하면 OOM 상태 중에 우선 순위가 높은 프로세스가 계속 실행되도록 할 수 있습니다. 각 프로세스에는 디렉토리인 /proc/PID
가 있습니다. 각 디렉터리에는 다음 파일이 포함됩니다.
-
oom_adj
-oom_adj
에 대한 유효한 점수는 -16 ~ +15 범위에 있습니다. 이 값은 프로세스의 성능 풋프린트를 계산하는데 사용되며, 다른 요인 중 프로세스 실행 기간을 고려합니다. -
oom_score
-oom_adj
의 값을 사용하여 계산된 알고리즘의 결과를 포함합니다.
메모리 부족 상태에서 oom_killer()
함수는 oom_score
가장 높은 프로세스를 종료합니다.
프로세스에 대한 oom_adj
파일을 편집하여 종료할 프로세스의 우선 순위를 지정할 수 있습니다.
사전 요구 사항
- 우선순위를 지정할 프로세스의 PID(프로세스 ID)를 확인합니다.
절차
프로세스의 현재
oom_score
를 표시합니다.# cat /proc/12465/oom_score 79872
프로세스의
oom_adj
콘텐츠를 표시합니다.# cat /proc/12465/oom_adj 13
oom_adj
의 값을 편집합니다.# echo -5 > /proc/12465/oom_adj
검증 단계
프로세스의 현재
oom_score
를 표시합니다.# cat /proc/12465/oom_score 78
- 표시된 값이 이전 값보다 낮은지 확인합니다.
17.4. 프로세스에 대한 메모리 부족 종료 비활성화
oom_killer()
를 예약된 값 -17
로 설정하여 프로세스에 대해 oom_
killer() 함수를 비활성화할 수 있습니다. 이렇게 하면 프로세스가 OOM 상태인 경우에도 계속 유지됩니다.
절차
oom_adj
의 값을-17
로 설정합니다.# echo -17 > /proc/12465/oom_adj
검증 단계
프로세스의 현재
oom_score
를 표시합니다.# cat /proc/12465/oom_score 0
-
표시된 값이
0
인지 확인합니다.
18장. tuna CLI를 사용하여 대기 시간 개선
tuna
CLI를 사용하여 시스템의 대기 시간을 개선할 수 있습니다. RHEL 9용 tuna CLI에는 argparse
구문 분석 모듈을 기반으로 하는 명령줄 인터페이스가 포함되어 있습니다. 인터페이스는 다음과 같은 기능을 제공합니다.
- 더 표준화된 명령 및 옵션 메뉴
-
인터페이스를 사용하면 사전 정의된 입력을 사용할 수 있으며
tuna
는 입력이 올바른 유형인지 확인할 수 있습니다. - 매개변수를 사용하는 방법에 대한 사용법 도움말 메시지를 자동으로 생성하고 잘못된 인수를 사용하여 오류 메시지를 제공합니다.
18.1. 사전 요구 사항
-
tuna
및python-linux-procfs
패키지가 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
18.2. tuna
CLI
tuna
CLI(명령줄 인터페이스)는 시스템을 변경하는 데 도움이 되는 도구입니다.
tuna
툴은 실행 중인 시스템에서 사용하도록 설계되었으며 변경 사항이 즉시 수행됩니다. 이를 통해 모든 애플리케이션별 측정 툴이 변경 후 즉시 시스템 성능을 확인하고 분석할 수 있습니다.
이제 tuna
CLI에 명령 세트가 있으며 이전에는 작업 옵션이었습니다. 이러한 명령은 다음과 같습니다.
- isolate
-
CPU-LIST
에서 모든 스레드와 IRQ를 멀리 이동합니다. - include
-
CPU-LIST
에서 실행되도록 모든 스레드를 구성합니다. - 이동
-
특정 엔티티를
CPU-LIST
로 이동합니다. - spread
-
선택한 엔티티를
CPU-LIST
에 분산시킵니다. - priority
-
POLICY
및ECDHERIO
와 같은 스레드 스케줄러 튜닝 가능 항목을 설정합니다. - run
- 새 프로세스를 분기하고 명령을 실행합니다.
- 저장
-
kthreads
sched
튜닝 가능 항목을 10.0.0.1
NAME에
저장합니다. - apply
- 프로필에 정의된 변경 사항을 적용합니다.
- show_threads
- 스레드 목록을 표시합니다.
- show_irqs
-
IRQ
목록을 표시합니다. - show_configs
- 기존 프로필 목록을 표시합니다.
- what_is
- 선택한 엔터티에 대한 도움말을 제공합니다.
- gui
- GUI(그래픽 사용자 인터페이스)를 시작합니다.
tuna -h
명령을 사용하여 명령을 볼 수 있습니다. 각 명령에는 tuna <command> -h
명령으로 볼 수 있는 선택적 인수가 있습니다. 예를 들어 tuna isolate -h
명령을 사용하면 isolate
에 대한 옵션을 볼 수 있습니다.
18.3. tuna
CLI를 사용하여 CPU 격리
tuna
CLI를 사용하여 여러 전용 CPU의 사용자 프로세스에서 인터럽트(IRQ)를 분리하여 실시간 환경에서 대기 시간을 최소화할 수 있습니다. CPU 분리에 대한 자세한 내용은 Interrupt 및 프로세스 바인딩 을 참조하십시오.
사전 요구 사항
-
tuna
및python-linux-procfs
패키지가 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
절차
하나 이상의 CPU를 분리합니다.
# tuna isolate --cpus=<cpu_list>
cpu_list
는 쉼표로 구분된 목록 또는 격리할 CPU 범위입니다.예를 들면 다음과 같습니다.
# tuna isolate --cpus=0,1
또는
# tuna isolate --cpus=0-5
18.4. tuna
CLI를 사용하여 지정된 CPU로 인터럽트 이동
tuna
CLI를 사용하여 인터럽트(IRQ)를 전용 CPU로 이동하여 실시간 환경에서 대기 시간을 최소화하거나 제거할 수 있습니다. IRQ 이동에 대한 자세한 내용은 Interrupt 및 process binding 을 참조하십시오.
사전 요구 사항
-
tuna
및python-linux-procfs
패키지가 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
절차
IRQ 목록이 연결된 CPU를 나열합니다.
# tuna show_irqs --irqs=<irq_list>
irq_list
는 연결된 CPU를 나열하려는 IRQ의 쉼표로 구분된 목록입니다.예를 들면 다음과 같습니다.
# tuna show_irqs --irqs=128
IRQ 목록을 CPU 목록에 연결합니다.
# tuna move --irqs=irq_list --cpus=<cpu_list>
irq_list
는 쉼표로 구분된 IRQ 목록입니다.cpu_list
는 쉼표로 구분된 CPU 목록이며, cpu_list는 해당 CPU가 연결될 CPU의 쉼표로 구분된 목록입니다.예를 들면 다음과 같습니다.
# tuna move --irqs=128 --cpus=3
검증
IRQ를 지정된 CPU로 이동하기 전과 후에 선택한 IRQ의 상태를 지정된 CPU로 비교합니다.
# tuna show_irqs --irqs=128
18.5. tuna
CLI를 사용하여 프로세스 스케줄링 정책 및 우선순위 변경
tuna
CLI를 사용하여 프로세스 스케줄링 정책 및 우선 순위를 변경할 수 있습니다.
사전 요구 사항
-
tuna
및python-linux-procfs
패키지가 설치됩니다. 시스템에 대한 root 권한이 있습니다.
참고OTHER
및BATCH
스케줄링 정책을 할당하려면 루트 권한이 필요하지 않습니다.
절차
스레드에 대한 정보를 봅니다.
# tuna show_threads --threads=<thread_list>
thread_list
는 표시할 프로세스의 쉼표로 구분된 목록입니다.예를 들면 다음과 같습니다.
# tuna show_threads --threads=42369,42416,43859
프로세스 스케줄링 정책 및 스레드의 우선 순위를 수정합니다.
# tuna priority scheduling_policy:priority_number --threads=<thread_list>
-
thread_list
는 예약 정책 및 우선 순위가 있는 프로세스의 쉼표로 구분된 목록입니다. scheduling_policy
는 다음 중 하나입니다.- OTHER
- BATCH
- FIFO - First Out
- RR - Round Robin
priority_number
는 0에서 99 사이의 우선 순위 번호입니다. 여기서0
은 우선 순위가 아니며99
가 가장 높은 우선 순위입니다.참고OTHER
및BATCH
스케줄링 정책은 우선 순위를 지정할 필요가 없습니다. 또한, 유일하게 유효한 우선순위(지정된 경우)는0
입니다.FIFO
및RR
스케줄링 정책에는1
이상의 우선 순위가 필요합니다.예를 들면 다음과 같습니다.
-
# tuna priority FIFO:1 --threads=42369,42416,43859
검증
- 스레드의 정보를 보고 정보가 변경되는지 확인합니다.
# tuna show_threads --threads=42369,42416,43859
19장. 스케줄러 우선순위 설정
Red Hat Enterprise Linux for Real Time 커널을 사용하면 스케줄러 우선 순위를 세밀하게 제어할 수 있습니다. 또한 애플리케이션 수준 프로그램을 커널 스레드보다 높은 우선 순위로 예약할 수 있습니다.
스케줄러 우선순위를 설정하면 결과가 발생할 수 있으며 중요 커널 프로세스가 필요에 따라 실행되지 않는 경우 시스템이 응답하지 않거나 예기치 않게 작동할 수 있습니다. 궁극적으로 올바른 설정은 워크로드에 따라 다릅니다.
19.1. 스레드 스케줄링 우선순위 보기
스레드 우선순위는 0
(최저 우선 순위)에서 99
(최고 우선 순위) 사이의 일련의 수준을 사용하여 설정됩니다. systemd
서비스 관리자를 사용하여 커널 부팅 후 스레드의 기본 우선 순위를 변경할 수 있습니다.
절차
실행 중인 스레드의 스케줄링 우선 순위를 보려면 tuna 유틸리티를 사용합니다.
# tuna --show_threads thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 2 OTHER 0 0xfff 451 3 kthreadd 3 FIFO 1 0 46395 2 ksoftirqd/0 5 OTHER 0 0 11 1 kworker/0:0H 7 FIFO 99 0 9 1 posixcputmr/0 ...[output truncated]...
19.2. 부팅 중 서비스 우선 순위 변경
systemd
를 사용하면 부팅 프로세스 중에 시작된 서비스의 실시간 우선 순위를 설정할 수 있습니다.
장치 구성 지시문은 부팅 프로세스 중에 서비스의 우선 순위를 변경하는 데 사용됩니다. 부팅 프로세스 우선 순위 변경은 /etc/systemd/system/service .system.d/priority.conf의서비스 섹션에 있는 다음 지시문을 사용하여 수행됩니다.
CPUSchedulingPolicy=
실행된 프로세스에 대한 CPU 스케줄링 정책을 설정합니다. Linux에서 사용할 수 있는 스케줄링 클래스 중 하나를 가져옵니다.
-
기타
-
일괄 처리
-
idle
-
fifo
-
rr
CPUSchedulingPriority=
실행된 프로세스의 CPU 스케줄링 우선 순위를 설정합니다. 사용 가능한 우선 순위 범위는 선택한 CPU 스케줄링 정책에 따라 다릅니다. 실시간 스케줄링 정책의 경우 1
(최저 우선 순위)에서 99
(최고 우선 순위) 사이의 정수를 사용할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
- 부팅 시 실행되는 서비스입니다.
절차
기존 서비스의 경우:
서비스에 대한 보조 서비스 구성 디렉터리 파일을 생성합니다.
# cat <<-EOF > /etc/systemd/system/mcelog.system.d/priority.conf
[SERVICE]
섹션의 파일에 스케줄링 정책 및 우선 순위를 추가합니다.예를 들면 다음과 같습니다.
[SERVICE] CPUSchedulingPolicy=fifo CPUSchedulingPriority=20 EOF
systemd
스크립트 구성을 다시 로드합니다.# systemctl daemon-reload
서비스를 다시 시작합니다.
# systemctl restart mcelog
검증
서비스의 우선 순위를 표시합니다.
$ tuna -t mcelog -P
출력에는 서비스의 구성된 우선 순위가 표시됩니다.
예를 들면 다음과 같습니다.
thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 826 FIFO 20 0,1,2,3 13 0 mcelog
추가 리소스
19.3. 서비스의 CPU 사용량 구성
systemd
를 사용하여 서비스를 실행할 수 있는 CPU를 지정할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
서비스에 대한 보조 서비스 구성 디렉터리 파일을 생성합니다.
# md sscd
[SERVICE]
섹션의CPUAffinity
속성을 사용하여 서비스에 사용할 CPU를 파일에 추가합니다.예를 들면 다음과 같습니다.
[SERVICE] CPUAffinity=0,1 EOF
systemd 스크립트 구성을 다시 로드합니다.
# systemctl daemon-reload
서비스를 다시 시작합니다.
# systemctl restart service
검증
지정된 서비스가 제한된 CPU를 표시합니다.
$ tuna -t mcelog -P
여기서
service
는 지정된 서비스입니다.다음 출력에서는
mcelog
서비스가 CPU 0 및 1로 제한됨을 보여줍니다.thread ctxt_switches pid SCHED_ rtpri affinity voluntary nonvoluntary cmd 12954 FIFO 20 0,1 2 1 mcelog
:_content-type: REFERENCE
19.4. 우선순위 맵
스케줄러 우선순위는 그룹에 정의되며, 일부 그룹은 특정 커널 함수로 전용됩니다.
표 19.1. 스레드 우선 순위 테이블
우선 순위 | 스레드 | 설명 |
---|---|---|
1 | 낮은 우선순위의 커널 스레드 |
이 우선순위는 일반적으로 10.0.0.1 |
2 - 49 | 사용 가능 | 일반적인 애플리케이션 우선순위에 사용되는 범위입니다. |
50 | 기본 hard-IRQ 값 | 이 우선순위는 하드웨어 기반 인터럽트의 기본값입니다. |
51 - 98 | 우선순위가 높은 스레드 |
주기적으로 실행되고 빠른 응답 시간이 필요한 스레드에는 이 범위를 사용합니다. 낮은 수준의 인터럽트에 대한 응답을 방지하기 때문에 CPU 바인딩 스레드에는 이 범위를 |
99 | 워치독 및 마이그레이션 | 가장 높은 우선 순위에서 실행해야 하는 시스템 스레드입니다. |
19.5. 추가 리소스
20장. 네트워크 결정성 팁
TCP는 대기 시간에 큰 영향을 미칠 수 있습니다. TCP는 효율성을 확보하고, 정체를 제어하고, 안정적인 제공을 보장하기 위해 대기 시간을 추가합니다. 튜닝할 때 다음 사항을 고려하십시오.
- Do you need ordered delivery?
패킷 손실을 방지할 필요가 있습니까?
두 번 이상 패킷을 전송하면 지연이 발생할 수 있습니다.
TCP를 사용해야 합니까?
소켓에서
TCP_NODELAY
를 사용하여 Nagle 버퍼링 알고리즘을 비활성화하는 것이 좋습니다. Nagle 알고리즘은 작은 발신 패킷을 수집하여 한 번에 모두 전송하며 대기 시간에 심각한 영향을 미칠 수 있습니다.
20.1. 병합 중단
처리량이 우선 순위인 대량의 데이터를 전송하는 시스템에서는 기본값을 사용하거나 병합을 늘리면 처리량이 증가하고 CPU에 도달한 인터럽트 수가 줄어들 수 있습니다. 신속한 네트워크 대응이 필요한 시스템의 경우, 병합을 줄이거나 비활성화하는 것이 좋습니다.
인터럽트 수를 줄이기 위해 패킷을 수집하고 패킷 컬렉션에 대해 단일 인터럽트를 생성할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
병합 인터럽트를 활성화하려면
--coalesce
옵션을 사용하여ethtool
명령을 실행합니다.# ethtool -C tun0
검증
병합 인터럽트가 활성화되어 있는지 확인합니다.
# ethtool -c tun0
Coalesce parameters for tun0:
Adaptive RX: n/a TX: n/a
stats-block-usecs: n/a
sample-interval: n/a
pkt-rate-low: n/a
pkt-rate-high: n/a
rx-usecs: n/a
rx-frames: 0
rx-usecs-irq: n/a
rx-frames-irq: n/a
tx-usecs: n/a
tx-frames: n/a
tx-usecs-irq: n/a
tx-frames-irq: n/a
rx-usecs-low: n/a
rx-frame-low: n/a
tx-usecs-low: n/a
tx-frame-low: n/a
rx-usecs-high: n/a
rx-frame-high: n/a
tx-usecs-high: n/a
tx-frame-high: n/a
CQE mode RX: n/a TX: n/a
20.2. 네트워크 정체 방지
I/O 스위치는 종종 전체 버퍼로 인해 네트워크 데이터가 빌드되는 백업 압축의 영향을 받을 수 있습니다. pause 매개변수를 변경하고 네트워크 혼잡을 방지할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
pause 매개변수를 변경하려면
-A
옵션을 사용하여ethtool
명령을 실행합니다.# ethtool -A enp0s31f6
검증
pause 매개변수가 변경되었는지 확인합니다.
# ethtool -a enp0s31f6
Pause parameters for enp0s31f6:
Autonegotiate: on
RX: on
TX: on
20.3. 네트워크 프로토콜 통계 모니터링
netstat
명령을 사용하여 네트워크 트래픽을 모니터링할 수 있습니다.
절차
네트워크 트래픽을 모니터링하려면 다음을 수행합니다.
$ netstat -s
Ip:
Forwarding: 1
30817508 total packets received
2927 forwarded
0 incoming packets discarded
30813320 incoming packets delivered
19184491 requests sent out
181 outgoing packets dropped
2628 dropped because of missing route
Icmp
29450 ICMP messages received
213 input ICMP message failed
ICMP input histogram:
destination unreachable: 29431
echo requests: 19
10141 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 10122
echo replies: 19
IcmpMsg:
InType3: 29431
InType8: 19
OutType0: 19
OutType3: 10122
Tcp:
162638 active connection openings
89 passive connection openings
38908 failed connection attempts
17869 connection resets received
48 connections established
8456952 segments received
9323882 segments sent out
69885 segments retransmitted
1143 bad segments received
56209 resets sent
Udp:
21929780 packets received
1319 packets to unknown port received
712919 packet receive errors
10134989 packets sent
712919 receive buffer errors
180 send buffer errors
IgnoredMulti: 39231
20.4. 추가 리소스
-
ethtool(8)
매뉴얼 페이지 -
netstat(8)
매뉴얼 페이지
21장. trace-cmd를 사용하여 대기 시간 추적
trace-cmd
유틸리티는 ftrace
유틸리티의 프런트 엔드입니다. trace-cmd
를 사용하면 /sys/kernel/debug/tracing/
디렉토리에 쓸 필요 없이 ftrace
작업을 활성화할 수 있습니다. trace-cmd
는 설치에 오버헤드를 추가하지 않습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
21.1. trace-cmd 설치
trace-cmd
유틸리티는 ftrace
유틸리티에 프런트 엔드를 제공합니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
trace-cmd
유틸리티를 설치합니다.# dnf install trace-cmd
21.2. trace-cmd 실행
trace-cmd
유틸리티를 사용하여 모든 ftrace
기능에 액세스할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
trace-cmd 명령을
입력합니다.여기서
명령은
ftrace
옵션입니다.참고전체 명령 및 옵션 목록은
trace-cmd(1)
매뉴얼 페이지를 참조하십시오. 대부분의 개별 명령에는 자체 도움말 페이지인trace-cmd-명령도
있습니다.
21.3. trace-cmd 예제
여러 trace-cmd
예제를 제공합니다.
예
myapp 이 실행되는 동안 커널 내에서 실행 중인 레코딩 기능을 활성화하고 시작합니다.
# trace-cmd record -p function myapp
이 레코드는 모든 CPU 및 모든 작업의 기능, 심지어 myapp 과 관련이 없는 작업을 기록합니다.
결과를 표시합니다.
# trace-cmd report
myapp 이 실행되는 동안 sched 로 시작하는 함수만 기록합니다.
# trace-cmd record -p function -l 'sched*' myapp
모든 IRQ 이벤트를 활성화합니다.
# trace-cmd start -e irq
wakeup_rt
tracer를 시작합니다.# trace-cmd start -p wakeup_rt
함수 추적을 비활성화하면서
preemptirqsoff
추적기를 시작합니다.# trace-cmd start -p preemptirqsoff -d
참고RHEL 8의
trace-cmd
버전은function-trace
옵션을 사용하는 대신ftrace_enabled
를 끕니다.trace-cmd start -p
함수를 사용하여ftrace
를 다시 활성화할 수 있습니다.시스템이
trace-cmd
전에 있던 상태를 복원하기 시작합니다.# trace-cmd start -p nop
이 문제는 시스템이 재시작되었는지의 여부인
trace-cmd
를 사용한 후debugfs
파일 시스템을 사용하려는 경우에 중요합니다.단일 추적 지점을 추적합니다.
# trace-cmd record -e sched_wakeup ls /bin
추적을 중지합니다.
# trace-cmd record stop
21.4. 추가 리소스
-
trace-cmd(1)
man page
22장. tuned-profiles-real-time을 사용하여 CPU 격리
애플리케이션 스레드에 가능한 가장 많은 실행 시간을 제공하려면 CPU를 격리할 수 있습니다. 따라서 CPU에서 관련 없는 작업을 최대한 많이 제거합니다. CPU 격리는 일반적으로 다음과 같습니다.
- 모든 사용자 공간 스레드 제거.
- 바인딩되지 않은 커널 스레드 제거. 커널 관련 바인딩된 스레드는 특정 CPU에 연결되어 있으며 이동할 수 없습니다.
-
시스템에서 각 Interrupt Request(IRQ) 번호
N
의/proc/irq/N/smp_affinity
속성을 수정하여 인터럽트 제거
[package]'tuned-profiles-realtime'package의 isolated_cores=cpulist
구성 옵션을 사용하여 CPU를 격리하는 작업을 자동화할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
22.1. 격리할 CPU 선택
격리할 CPU를 선택하려면 시스템의 CPU 토폴로지를 신중하게 고려해야 합니다. 다른 사용 사례에는 다른 구성이 필요합니다.
- 스레드가 캐시를 공유하여 서로 통신해야 하는 다중 스레드 애플리케이션이 있는 경우 동일한 NUMA 노드 또는 물리적 소켓에 보관해야 합니다.
- 관련이 없는 여러 실시간 애플리케이션을 실행하는 경우 CPU를 NUMA 노드 또는 소켓으로 분리하는 것이 적합할 수 있습니다.
hwloc
패키지는 lstopo-no-graphics
및 numactl
을 포함하여 CPU에 대한 정보를 얻는 데 유용한 유틸리티를 제공합니다.
사전 요구 사항
-
hwloc
패키지가 설치됩니다.
절차
물리적 패키지에서 사용 가능한 CPU의 레이아웃을 확인합니다.
# lstopo-no-graphics --no-io --no-legend --of txt
그림 22.1. lstopo-no-graphics를 사용하여 CPU 레이아웃 표시
이 명령은 사용 가능한 코어와 소켓 수와 NUMA 노드의 논리적 거리를 표시하므로 다중 스레드 애플리케이션에 유용합니다.
또한
hwloc-gui
패키지는 그래픽 출력을 생성하는lstopo
유틸리티를 제공합니다.노드 간 거리와 같은 CPU에 대한 자세한 정보를 확인합니다.
# numactl --hardware available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 node 0 size: 16159 MB node 0 free: 6323 MB node 1 cpus: 4 5 6 7 node 1 size: 16384 MB node 1 free: 10289 MB node distances: node 0 1 0: 10 21 1: 21 10
추가 리소스
-
hwloc>-<
; 매뉴얼 페이지
22.2. TuneD의 isolated_cores 옵션을 사용하여 CPU 격리
CPU 격리를 위한 초기 메커니즘은 커널 부팅 명령줄에 boot 매개변수 isolcpus=cpulist
를 지정하는 것입니다. RHEL for Real Time에 이 작업을 수행하는 권장 방법은 TuneD
데몬과 tuned-profiles-realtime
패키지를 사용하는 것입니다.
tuned-profiles-realtime
버전 2.19 이상에서는 기본 제공 함수 calc_isolated_cores
가 초기 CPU 설정을 자동으로 적용합니다. /etc/tuned/realtime->-<s.conf
구성 파일에는 기본 변수 콘텐츠가 isolated_cores=${f:calc_isolated_cores:2}
로 포함됩니다.
기본적으로 calc_isolated_cores
는 하우스키핑을 위해 소켓당 하나의 코어를 예약하고 나머지는 격리합니다. 기본 구성을 변경해야 하는 경우 /etc/tuned/realtime-anchors.conf
구성 파일의 isolated_cores=${f:calc_isolated_cores:2}
행을 주석 처리하고 TuneD의 isolated_cores
옵션을 사용하여 Isolating CPU의 절차 단계를 따릅니다.
사전 요구 사항
-
TuneD
및tuned-profiles-realtime
패키지가 설치됩니다. - 시스템에 대한 root 권한이 있습니다.
절차
-
루트 사용자로 텍스트 편집기에서
/etc/tuned/realtime->-<s.conf를
엽니다. isolated_cores=cpulist
를 설정하여 분리할 CPU를 지정합니다. CPU 번호와 범위를 사용할 수 있습니다.예:
isolated_cores=0-3,5,7
이는 코어 0, 1, 2, 3, 5, 7을 분리합니다.
NUMA 노드 0에 코어가 8개인 두 개의 소켓 시스템에서 NUMA 노드 1에 코어 4-8이 있으며 멀티 스레드 애플리케이션에 두 개의 코어를 할당하는 경우 다음을 지정합니다.
isolated_cores=4,5
이렇게 하면 사용자 공간 스레드가 CPU 4 및 5에 할당되지 않습니다.
관련이 없는 애플리케이션의 다른 NUMA 노드에서 CPU를 선택하려면 다음을 지정합니다.
isolated_cores=0,4
이렇게 하면 모든 사용자 공간 스레드가 CPU 0 및 4에 할당되지 않습니다.
tuned-adm
유틸리티를 사용하여 실시간TuneD
프로필을 활성화합니다.# tuned-adm profile realtime
- 변경 사항을 적용하려면 머신을 재부팅합니다.
검증
커널 명령 줄에서
isolcpus
매개변수를 검색합니다.$ cat /proc/cmdline | grep isolcpus BOOT_IMAGE=/vmlinuz-4.18.0-305.rt7.72.el8.x86_64 root=/dev/mapper/rhel_foo-root ro crashkernel=auto rd.lvm.lv=rhel_foo/root rd.lvm.lv=rhel_foo/swap console=ttyS0,115200n81 isolcpus=0,4
22.3. nohz 및 nohz_full 매개변수를 사용하여 CPU 격리
nohz
및 nohz_full
매개 변수는 지정된 CPU의 활동을 수정합니다. 이러한 커널 부팅 매개변수를 활성화하려면 realtime-virtual-host
,realtime-virtual-guest
또는 cpu-partitioning
의 다음 TuneD 프로필 중 하나를 사용해야 합니다.
nohz=on
특정 CPU 세트의 타이머 활동을 줄입니다.
nohz
매개변수는 주로 유휴 CPU의 타이머 인터럽트를 줄이는 데 사용됩니다. 이를 통해 유휴 CPU를 감소 모드로 실행할 수 있으므로 건전지 수명을 유지할 수 있습니다. 실시간 응답 시간에 직접 유용하지는 않지만nohz
매개변수는 실시간 응답 시간에 부정적인 영향을 미치지 않습니다. 그러나nohz
매개변수는 실시간 성능에 긍정적인 영향을 미치는nohz_full
매개변수를 활성화하는 데 필요합니다.nohz_full=cpulist
-
nohz_full
매개 변수는 지정된 CPU 목록의 타이머 눈금을 다르게 처리합니다. CPU가nohz_full
CPU로 지정되어 있고 CPU에 실행 가능한 작업이 하나만 있는 경우 커널은 해당 CPU로 타이머 컷 전송을 중지합니다. 결과적으로 애플리케이션을 실행하는 데 더 많은 시간을 할애하고 인터럽트 및 컨텍스트 전환에 소요되는 시간을 줄일 수 있습니다.
추가 리소스
23장. ScanSetting_OTHER 작업 마이그레이션 제한
sched_nr_migrate
변수를 사용하여 gRPC_OTHER
가 다른 CPU로 마이그레이션하는 작업을 제한할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
23.1. 작업 마이그레이션
a ECDHE_OTHER
작업이 다른 많은 작업을 생성하는 경우 모두 동일한 CPU에서 실행됩니다. 마이그레이션
작업 또는 softirq
는 유휴 상태의 CPU에서 실행할 수 있도록 이러한 작업의 균형을 맞추려고 합니다.
sched_nr_migrate
옵션을 조정하여 한 번에 이동할 작업 수를 지정할 수 있습니다. 실시간 작업은 마이그레이션 방법이 다르기 때문에 이 문제의 직접적인 영향을 받지 않습니다. 그러나 softirq
가 작업을 이동할 때 실행 대기열 회전이 잠기므로 인터럽트를 비활성화합니다.
이동해야 하는 작업이 많이 있는 경우 인터럽트가 비활성화된 동안 발생하므로 타이머 이벤트 또는 발생 시 동시에 발생할 수 있습니다. 이로 인해 sched_nr_migrate
가 큰 값으로 설정된 경우 실시간 작업에 심각한 대기 시간이 발생할 수 있습니다.
23.2. sched_nr_migrate 변수를 사용하여 CloudEvent_OTHER 작업 마이그레이션 제한
sched_nr_migrate
변수를 늘리면 실시간 대기 시간을 고려하여 많은 작업을 생성하는 gRPC _OTHER
스레드의 고성능이 제공됩니다.
low real-time task latency at the cost of ECDHE_OTHER
task performance, value must be lowered. 기본값은 8
입니다.
절차
sched_nr_migrate
변수 값을 조정하려면 값을/proc/sys/kernel/sched_nr_migrate
로 직접 에코합니다.# echo 2 > /proc/sys/kernel/sched_nr_migrate
검증
/proc/sys/kernel/sched_nr_migrate
의 내용을 확인합니다.# cat > /proc/sys/kernel/sched_nr_migrate 2
24장. TCP 성능 급증 감소
TCP 타임스탬프를 생성하면 TCP 성능이 급증할 수 있습니다. sysctl
명령은 TCP 관련 항목의 값을 제어하고, /proc/sys/net/ipv4/tcp_timestamps
에 있는 timestamps 커널 매개 변수를 설정합니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
24.1. TCP 타임스탬프 비활성화
TCP 타임스탬프를 끄면 TCP 성능이 저하될 수 있습니다.
절차
TCP 타임스탬프를 끄십시오.
# sysctl -w net.ipv4.tcp_timestamps=0 net.ipv4.tcp_timestamps = 0
출력은
net.ip4.tcp_timestamps
옵션 값이0
임을 보여줍니다. 즉, TCP 타임스탬프는 비활성화되어 있습니다.
24.2. TCP 타임스탬프 설정
타임스탬프를 생성하면 TCP 성능이 급증할 수 있습니다. TCP 타임스탬프를 비활성화하여 TCP 성능 급증을 줄일 수 있습니다. TCP 타임스탬프 생성이 TCP 성능 급증을 유발하지 않는 경우 활성화할 수 있습니다.
절차
TCP 타임스탬프를 활성화합니다.
# sysctl -w net.ipv4.tcp_timestamps=1 net.ipv4.tcp_timestamps = 1
출력은
net.ip4.tcp_timestamps
값이1
임을 보여줍니다. 즉, TCP 타임스탬프가 활성화됩니다.
24.3. TCP 타임스탬프 상태 표시
TCP 타임스탬프 생성 상태를 볼 수 있습니다.
절차
TCP 타임스탬프 생성 상태를 표시합니다.
# sysctl net.ipv4.tcp_timestamps net.ipv4.tcp_timestamps = 0
값
1
은 타임스탬프가 생성 중임을 나타냅니다. 값0
은 타임스탬프가 생성되지 않음을 나타냅니다.
25장. R CloudEvent 콜백을 사용하여 CPU 성능 향상
Read-Copy-Update
(RECDHE ) 시스템은 커널 내부의 스레드를 상호 제외하기 위한 잠금 해제 메커니즘입니다. RECDHE 작업을 수행하면 메모리가 안전해질 때 호출이 CPU에 대기되는 경우가 있습니다.
R CloudEvent 콜백을 사용하여 CPU 성능을 개선하려면 다음을 수행합니다.
- CPU 콜백 실행의 후보가 되는 CPU를 제거할 수 있습니다.
- 모든 Ranchor 콜백을 처리하도록 CPU를 할당할 수 있습니다. 이 CPU를 하우스키핑 CPU라고 합니다.
- CPU는 R ScanSetting 오프로드 스레드를 유발하는 책임에서 벗어날 수 있습니다.
이 조합은 사용자 워크로드에 전용된 CPU에 대한 간섭을 줄입니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
-
tuna
패키지가 설치됨
25.1. RLoadBalancer 콜백 오프로드
rcu_nocbs
및 rcu_nocb_poll
커널 매개변수를 사용하여 RLoadBalancer 콜백을 오프로드할 수 있습니다.
절차
R SSDT 콜백 실행 후보에서 하나 이상의 CPU를 제거하려면
rcu_nocbs
커널 매개변수의 CPU 목록을 지정합니다. 예를 들면 다음과 같습니다.rcu_nocbs=1,4-6
또는
rcu_nocbs=3
두 번째 예는 커널에 CPU 3이 호출되지 않음 CPU임을 지시합니다. 즉, R CloudEvent 콜백은 CPU 3에 고정된
rcuc/$CPU
스레드에서 실행되지 않지만rcuo/$CPU
스레드에서 수행됩니다. 이 trhead를 하우스키핑 CPU로 이동하여 CPU 3이 RECDHE 콜백 작업이 할당되지 않도록 할 수 있습니다.
25.2. Ranchor 콜백
하우스키핑 CPU를 할당하여 모든 RECDHE 콜백 스레드를 처리할 수 있습니다. 이렇게 하려면 tuna
명령을 사용하고 모든 RECDHE 콜백을 하우스키핑 CPU로 이동합니다.
절차
RECDHE 콜백 스레드를 하우스키핑 CPU로 이동합니다.
# tuna --threads=rcu --cpus=x --move
여기서
x
는 하우스키핑 CPU의 CPU 번호입니다.
이 작업은 CPU X 이외의 모든 CPU가 RECDHE 콜백 스레드를 처리하지 못하도록 합니다.
25.3. RECDHE 오프로드 스레드를 축소하지 못하도록 CPU 조정
Ranchor 오프로드 스레드는 다른 CPU에서 RECDHE 콜백을 수행할 수 있지만 각 CPU는 해당 R ScanSetting 오프로드 스레드를 재지정해야 합니다. 이 책임에서 CPU를 줄일 수 있습니다.
절차
rcu_nocb_poll
커널 매개변수를 설정합니다.이 명령을 실행하면 타이머가 주기적으로 Ranchor 오프로드 스레드를 발생시켜 실행할 콜백이 있는지 확인합니다.
25.4. 추가 리소스
26장. ftrace를 사용하여 대기 시간 추적
ftrace
유틸리티는 RHEL for Real Time 커널과 함께 제공되는 진단 기능 중 하나입니다. ftrace
는 개발자가 사용자 공간 외부에서 발생하는 대기 시간 및 성능 문제를 분석하고 디버깅하는 데 사용할 수 있습니다. ftrace
유틸리티에는 다양한 방법으로 유틸리티를 사용할 수 있는 다양한 옵션이 있습니다. 컨텍스트 스위치를 추적하거나, 우선 순위가 높은 작업이 발생하는 시간, 인터럽트 길이가 비활성화되거나 지정된 기간 동안 실행되는 모든 커널 함수를 나열하는 데 사용할 수 있습니다.
함수 추적기와 같은 ftrace
추적기 중 일부는 과도하게 많은 양의 데이터를 생성할 수 있으므로 추적 로그 분석을 시간이 많이 소요되는 작업으로 변환할 수 있습니다. 그러나 애플리케이션이 중요한 코드 경로에 도달할 때만 추적기를 시작하고 종료하도록 지시할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
26.1. ftrace 유틸리티를 사용하여 대기 시간 추적
ftrace
유틸리티를 사용하여 대기 시간을 추적할 수 있습니다.
절차
시스템에서 사용 가능한 추적기를 확인합니다.
# cat /sys/kernel/debug/tracing/available_tracers function_graph wakeup_rt wakeup preemptirqsoff preemptoff irqsoff function nop
ftrace
의 사용자 인터페이스는debugfs
내의 일련의 파일입니다.ftrace
파일은/sys/kernel/debug/tracing/
디렉터리에도 있습니다./sys/kernel/debug/tracing/
디렉터리로 이동합니다.# cd /sys/kernel/debug/tracing
이 디렉터리의 파일은 root 사용자만 수정할 수 있습니다. 추적을 사용하면 시스템 성능에 영향을 미칠 수 있습니다.
추적 세션을 시작하려면 다음을 수행합니다.
-
/sys/kernel/debug/tracing/available_tracer의 사용 가능한 추적기 목록에서 사용할 추적기를 선택합니다
. 선택기 이름을
/sys/kernel/debug/tracing/current_tracer
에 삽입합니다.# echo preemptoff > /sys/kernel/debug/tracing/current_tracer
참고echo 명령과 함께 단일 '>'를 사용하면 파일의 기존 값을 덮어씁니다. 파일에 값을 추가하려면 대신 '>>'을 사용합니다.
-
function-trace 옵션은
wakeup_rt
,preemptirqsoff
로 대기 시간을 추적하기 때문에 유용합니다. preemptirqsoff는 오버헤드를 초과할 수 있는함수 추적을
자동으로 활성화합니다.function
및function_graph
tracing이 활성화되어 있는지 확인합니다.# cat /sys/kernel/debug/tracing/options/function-trace 1
-
값이
1
이면 함수 및function
_graph 추적이 -
값이
0
이면함수
및function_graph
추적이 비활성화됩니다.
-
값이
기본적으로 함수 및
function
_graphfunction
_graph/sys/kernel/debug/tracing/options/function-trace
파일로 에코합니다.# echo 0 > /sys/kernel/debug/tracing/options/function-trace # echo 1 > /sys/kernel/debug/tracing/options/function-trace
중요echo
명령을 사용하는 경우 값과 > 문자 사이에 공백 문자를 배치해야 합니다.쉘 프롬프트에서
0
>,1
> , 1> 및2
>를 사용하여 표준 입력, 표준 출력 및 표준 오류를 나타냅니다. 실수로 사용하면 예기치 않은 추적 출력이 발생할 수 있습니다./debugfs/tracing/
디렉터리에 있는 다양한 파일의 값을 변경하여 추적자의 세부 정보 및 매개 변수를 조정합니다.예를 들면 다음과 같습니다.
irqsoff
, Preempirqsoff
,preempirqsoff
및wakeup
추적기는 지속적으로 대기 시간을 모니터링합니다.tracing_max_latency
에 기록된 것보다 더 큰 대기 시간을 기록하는 경우 해당 대기 시간의 추적이 기록되고tracing_max_latency
가 새 최대 시간으로 업데이트됩니다. 이러한 방식으로tracing_max_latency
는 마지막 재설정 이후 항상 가장 높은 대기 시간을 표시합니다.최대 대기 시간을 재설정하려면
0
을tracing_max_latency
파일로 에코합니다.# echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
설정된 양보다 대기 시간만 표시하려면 마이크로초 단위로 양을 에코합니다.
# echo 200 > /sys/kernel/debug/tracing/tracing_max_latency
추적 임계값이 설정되면 최대 대기 시간 설정을 덮어씁니다. 임계값보다 큰 대기 시간이 기록되면 최대 대기 시간에 관계없이 기록됩니다. 추적 파일을 검토할 때 마지막으로 기록된 대기 시간만 표시됩니다.
임계값을 설정하려면 대기 시간을 기록해야 하는 마이크로초 수를 에코합니다.
# echo 200 > /sys/kernel/debug/tracing/tracing_thresh
추적 로그를 확인합니다.
# cat /sys/kernel/debug/tracing/trace
추적 로그를 저장하려면 다른 파일에 복사합니다.
# cat /sys/kernel/debug/tracing/trace > /tmp/lat_trace_log
추적 중인 함수를 확인합니다.
# cat /sys/kernel/debug/tracing/set_ftrace_filter
-
/sys/kernel/debug/tracing/set_ftrace_filter
의 설정을 편집하여 추적되는 함수를 필터링합니다. 파일에 필터가 지정되지 않은 경우 모든 함수가 추적됩니다. 필터 설정을 변경하려면 추적할 함수의 이름을 에코합니다. 필터를 사용하면 검색어 시작 또는 끝에서 '*' 와일드카드를 사용할 수 있습니다.
예를 들면 ftrace 예제 를 참조하십시오.
26.2. ftrace 파일
다음은 /sys/kernel/debug/tracing/
디렉토리의 기본 파일입니다.
ftrace 파일
- Trace
-
ftrace
추적의 출력을 보여주는 파일입니다. 이 파일을 읽을 때 추적이 중지되고 읽은 이벤트를 사용하지 않기 때문에 실제로 추적의 스냅샷입니다. 즉, 사용자가 추적을 비활성화하고 이 파일을 읽으면 읽힐 때마다 동일한 항목을 보고합니다. - trace_pipe
-
추적을 읽을 때
ftrace
추적의 출력을 보여주는 파일은 실시간으로 표시됩니다. 생산자/소유자 추적입니다. 즉, 각 읽기는 읽은 이벤트를 사용합니다. 이는 읽은 대로 추적을 중지하지 않고 활성 추적을 읽는 데 사용할 수 있습니다. - available_tracers
- 커널로 컴파일된 ftrace 추적기 목록입니다.
- current_tracer
-
ftrace
추적기를 활성화하거나 비활성화합니다. - 이벤트
- 추적할 이벤트가 포함되어 있고 이벤트를 활성화 또는 비활성화하고 이벤트에 대한 필터를 설정하는 데 사용할 수 있는 디렉터리입니다.
- tracing_on
-
ftrace
버퍼에 대한 레코딩을 비활성화하고 활성화합니다.tracing_on
파일을 통해 추적을 비활성화해도 커널 내부에서 발생하는 실제 추적은 비활성화되지 않습니다. 버퍼 쓰기만 비활성화합니다. 추적을 수행하는 작업은 계속 발생하지만 데이터는 아무데도 이동하지 않습니다.
26.3. ftrace 추적기
커널 구성 방법에 따라 지정된 커널에서 일부 추적기를 사용할 수 있는 것은 아닙니다. RHEL for Real Time 커널의 경우 추적 및 디버그 커널에는 프로덕션 커널과 다른 추적기가 있습니다. 이는 추적기가 커널에 구성되어 있지만 활성 상태가 아닌 경우 일부 추적기에서 눈에 띄는 오버헤드가 있기 때문입니다. 이러한 추적자는 trace
및 debug
커널에만 활성화됩니다.
Tracers
- function
- 가장 널리 적용할 수 있는 추적기 중 하나입니다. 커널 내에서 함수 호출을 추적합니다. 이로 인해 추적된 함수 수에 따라 눈에 띄는 오버헤드가 발생할 수 있습니다. 활성화되지 않으면 약간의 오버헤드가 발생합니다.
- function_graph
function_graph
tracer는 시각적으로 원하는 결과를 제공하도록 설계되었습니다. 또한 이 추적기에서는 함수의 종료를 추적하여 커널의 함수 호출 흐름을 표시합니다.참고이 추적기에는 활성화된 경우
함수
추적기보다 많은 오버헤드가 있지만 비활성화되면 동일한 낮은 오버헤드가 발생합니다.- wakeup
- 모든 CPU에서 발생하는 활동을 보고하는 전체 CPU 추적기입니다. 해당 작업이 실시간 작업인지 여부에 관계없이 시스템에서 가장 높은 우선 순위 작업을 시작하는 데 걸리는 시간을 기록합니다. 비실시간 작업을 시작하는 데 걸리는 최대 시간을 기록하면 실시간 작업을 시작하는 데 걸리는 시간이 숨겨집니다.
- wakeup_rt
- 모든 CPU에서 발생하는 활동을 보고하는 전체 CPU 추적기입니다. 이는 예약된 시간까지 현재 가장 높은 우선 순위 작업에서 걸리는 시간을 기록합니다. 이 추적기에서는 실시간 작업의 시간만 기록합니다.
- preemptirqsoff
- 선점 또는 인터럽트를 비활성화하는 영역을 추적하고 선점 또는 인터럽트가 비활성화된 최대 시간을 기록합니다.
- preemptoff
- preemptirqsoff 추적기와 유사하지만 사전 교환이 비활성화된 최대 간격만 추적합니다.
- irqsoff
- preemptirqsoff 추적기와 유사하지만 인터럽트가 비활성화된 최대 간격만 추적할 수 있습니다.
- NOP
-
기본 추적기입니다. 이는 추적 기능을 제공하지 않지만, 이벤트가 모든 추적기와 인터리어링할 수 있으므로
nop
tracer는 이벤트 추적에 대한 특정 관심에 사용됩니다.
26.4. ftrace 예제
다음은 추적되는 함수 필터링을 변경하기 위한 여러 예제를 제공합니다. * 와일드카드는 단어의 시작과 끝에서 모두 사용할 수 있습니다. 예를 들면 *irq\*
는 이름에 irq 가 포함된 모든 기능을 선택합니다. 그러나 와일드카드는 단어 내에서 사용할 수 없습니다.
검색어와 와일드카드 문자를 이중 따옴표로 캡슐화하면 쉘이 현재 작업 디렉토리로 검색을 확장하지 않습니다.
필터의 예
schedule
기능만 추적합니다.# echo schedule > /sys/kernel/debug/tracing/set_ftrace_filter
lock
로 끝나는 모든 함수를 추적합니다.# echo "*lock" > /sys/kernel/debug/tracing/set_ftrace_filter
spin_
로 시작하는 모든 함수를 추적합니다.# echo "spin_*" > /sys/kernel/debug/tracing/set_ftrace_filter
이름에서
cpu
를 사용하여 모든 기능을 추적합니다.# echo "cpu" > /sys/kernel/debug/tracing/set_ftrace_filter
27장. 애플리케이션 타임스탬프
타임스탬프를 자주 수행하는 애플리케이션은 시계를 읽는 CPU 비용의 영향을 받습니다. 클럭을 읽는 데 사용된 높은 비용과 시간은 애플리케이션 성능에 부정적인 영향을 미칠 수 있습니다.
기본 시계보다 빠르고 읽기 메커니즘이 있는 하드웨어 시계를 선택하여 클럭을 읽는 비용을 줄일 수 있습니다.
RHEL for Real Time에서는 clock_gettime()
함수와 함께 POSIX 시계를 사용하여 가능한 가장 낮은 CPU 비용으로 클럭 읽기를 생성함으로써 추가 성능 향상을 얻을 수 있습니다.
이러한 이점은 높은 읽기 비용으로 하드웨어 시계를 사용하는 시스템에 더 큰 이점이 있습니다.
27.1. POSIX 클럭
POSIX는 시간 소스를 구현하고 표시하기 위한 표준입니다. 시스템의 다른 애플리케이션에 영향을 주지 않고 애플리케이션에 POSIX 시계를 할당할 수 있습니다. 이는 커널에 의해 선택되고 시스템 전체에 구현된 하드웨어 시계와 대조됩니다.
지정된 POSIX 시계를 읽는 데 사용되는 함수는 clock_gettime()
이며 < time.h>에서 정의됩니다
. clock_gettime()
과 커널 카운터는 시스템 호출입니다. 사용자 프로세스에서 clock_gettime()
을 호출하는 경우 :
-
해당 C 라이브러리(
glibc
)는sys_clock_gettime()
시스템 호출을 호출합니다. -
sys_clock_gettime()
은 요청된 작업을 수행합니다. -
sys_clock_gettime()
은 사용자 프로그램에 결과를 반환합니다.
그러나 사용자 애플리케이션에서 커널로 컨텍스트 전환에는 CPU 비용이 발생합니다. 이 비용이 매우 낮더라도 작업이 수천 번 반복되면 누적된 비용이 애플리케이션의 전반적인 성능에 영향을 미칠 수 있습니다. 커널로 컨텍스트 전환을 피하기 위해 CLOCK_MONOTONIC_COARSE
및 CLOCK_REALTIME_COARSE
POSIX 클럭에 대한 지원, 가상 동적 공유 오브젝트(VDSO) 라이브러리 기능의 형태로 클럭을 더 빠르게 읽을 수 있습니다.
_COARSE
클럭 변형 중 하나를 사용하여 clock_gettime()
에 의해 수행되는 시간 읽기는 커널 개입이 필요하지 않으며 사용자 공간에서 완전히 실행됩니다. 이로 인해 성능이 크게 향상됩니다. _COARSE
시계에 대한 시간 측정은 밀리초(ms) 해상도로, 1ms보다 작은 시간 간격은 기록되지 않습니다. POSIX 시계의 _COARSE
변형은 밀리 초 시계 해상도를 수용할 수 있는 모든 애플리케이션에 적합합니다.
_COARSE
접두사와 없이 POSIX 시계를 읽는 비용과 해결 방법을 비교하려면 RHEL for Real Time Reference 가이드를 참조하십시오.
27.2. clock_gettime의 _COARSE 시계 변형
다음 코드는 CLOCK_MONOTONIC_COARSE
POSIX 시계와 함께 clock_gettime
함수를 사용하는 코드의 예를 보여줍니다.
#include <time.h> main() { int rc; long i; struct timespec ts; for(i=0; i<10000000; i++) { rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); } }
위의 예제에서는 clock_gettime()
의 반환 코드를 확인하고 rc
변수 값을 확인하거나 ts
구조의 내용을 신뢰할 수 있는지 확인하는 검사를 추가하여 개선할 수 있습니다.
clock_gettime()
도움말 페이지는 보다 안정적인 애플리케이션 작성에 대한 자세한 정보를 제공합니다.
clock_gettime()
함수를 사용하는 프로그램은 gcc
명령줄에 -lrt
를 추가하여 rt
라이브러리와 연결되어야 합니다.
$ GCC clock_timing.c -o clock_timing -lrt
27.3. 추가 리소스
-
clock_gettime()
man page
28장. TCP_NODELAY를 사용하여 네트워크 대기 시간 개선
기본적으로 TCP
는 Nagle의 알고리즘을 사용하여 작은 발신 패킷을 수집하여 모두 한 번에 보냅니다. 이로 인해 대기 시간이 증가할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
28.1. TCP_NODELAY 사용의 영향
전송되는 모든 패킷에 대해 대기 시간이 짧은 애플리케이션은 TCP_NODELAY
옵션이 활성화된 소켓에서 실행되어야 합니다. 이렇게 하면 이벤트가 발생하는 즉시 커널에 버퍼 쓰기를 보냅니다.
- 참고
-
TCP_NODELAY
가 효과적이려면 애플리케이션은 작고 논리적으로 관련된 버퍼 쓰기를 피해야 합니다. 그렇지 않으면 이러한 작은 쓰기로 인해TCP
가 이러한 여러 버퍼를 개별 패킷으로 보내 전체 성능이 저하됩니다.
애플리케이션에 논리적으로 관련된 여러 버퍼가 있고 하나의 패킷으로 전송되어야 하는 경우 다음 해결 방법 중 하나를 적용하여 성능이 저하되지 않도록 합니다.
-
메모리에 연속된 패킷을 빌드한 다음
TCP
_NODELAY -
I/O 벡터를 만들고
TCP_NODELAY
로 구성된 소켓에서writev
명령을 사용하여 커널에 전달합니다. -
TCP_CORK
옵션을 사용합니다.TCP_CORK
는TCP
가 패킷을 전송하기 전에 애플리케이션이 코스크를 제거할 때까지 대기하도록 지시합니다. 이 명령을 실행하면 수신하는 버퍼가 기존 버퍼에 추가됩니다. 이렇게 하면 애플리케이션이 커널 공간에 패킷을 빌드할 수 있으므로 계층에 추상화를 제공하는 다른 라이브러리를 사용할 때 필요할 수 있습니다.
애플리케이션의 다양한 구성 요소에 의해 논리 패킷이 커널에 빌드된 경우 소켓을 분리하여 TCP
가 즉시 누적된 논리 패킷을 보낼 수 있어야 합니다.
28.2. TCP_NODELAY 활성화
TCP_NODELAY
옵션은 이벤트가 발생할 때 버퍼 쓰기를 커널에 전송하며 지연은 없습니다. setsockopt()
함수를 사용하여 TCP_NODELAY
를 활성화합니다.
절차
TCP
애플리케이션의.c
파일에 다음 행을 추가합니다.int one = 1; setsockopt(descriptor, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
- 파일을 저장하고 편집기를 종료합니다.
성능 저하를 방지하려면 다음 해결 방법 중 하나를 적용합니다.
-
메모리에 연속된 패킷을 빌드한 다음
TCP
_NODELAY -
I/O 벡터를 만들고
TCP_NODELAY
로 구성된 소켓에서writev
를 사용하여 커널에 전달합니다.
-
메모리에 연속된 패킷을 빌드한 다음
28.3. TCP_CORK 활성화
TCP_CORK
옵션은 소켓이 "cocorked"될 때까지 TCP
가 패킷을 전송하지 못하도록 합니다.
절차
TCP
애플리케이션의.c
파일에 다음 행을 추가합니다.int one = 1; setsockopt(descriptor, SOL_TCP, TCP_CORK, &one, sizeof(one));
- 파일을 저장하고 편집기를 종료합니다.
애플리케이션의 다양한 구성 요소에 의해 논리 패킷이 커널에 빌드되면
TCP_CORK
를 비활성화합니다.int zero = 0; setsockopt(descriptor, SOL_TCP, TCP_CORK, &zero, sizeof(zero));
TCP
는 애플리케이션에서 추가 패킷을 기다리지 않고 누적된 논리적 패킷을 즉시 전송합니다.
28.4. 추가 리소스
-
TCP>-&
lt; 매뉴얼 페이지 -
setsockopt(3p)
man page -
setsockopt(2)
man page
29장. CloudEvent를 사용하여 리소스 초과 방지
상호 제외(mutex) 알고리즘은 공통 리소스의 과다 사용을 방지하는 데 사용됩니다.
29.1. trigger options
상호 제외(mutex) 알고리즘은 공통 리소스를 사용하여 프로세스를 동시에 방지하는 데 사용됩니다. 빠른 사용자 공간 10.0.0.1(futex)은 커널 공간으로 컨텍스트 전환을 요구하지 않고 사용자 공간 스레드가 이미 다른 스레드에 의해 보유되지 않은 경우 사용자 공간 스레드를 클레임할 수 있는 툴입니다.
표준 속성, 비공개, 비재귀, 비로버스 및 우선순위가 없는 inherited-enabled로 pthread_mutex_t
오브젝트를 초기화하면 우선순위가 적용되지 않습니다. 이 오브젝트는 pthreads
API 및 RHEL for Real Time 커널에서 제공하는 ben fits를 제공하지 않습니다.
pthreads
API 및 RHEL for Real Time 커널의 이점을 얻으려면 pthread_mutexattr_t
오브젝트를 만듭니다. 이 개체는 futex에 대해 정의된 특성을 저장합니다.
이 용어는 POSIX
스레드(pthread
) constructs를 설명하는 데 사용됩니다.
29.2. attributes 특성 오브젝트 생성
CloudEvent에 대한 추가 기능을 정의하려면 pthread_mutexattr_t
오브젝트를 만듭니다. 이 개체는 futex에 대해 정의된 특성을 저장합니다. 이는 항상 수행해야 하는 기본적인 안전 절차입니다.
절차
다음 중 하나를 사용하여 CloudEvent 특성 오브젝트를 생성합니다.
-
pthread_mutex_t(my_mutex);
-
pthread_mutexattr_t(&my_mutex_attr);
-
pthread_mutexattr_init(&my_mutex_attr);
-
고급 attributes에 대한 자세한 내용은 고급 attributes를 참조하십시오.
29.3. 표준 속성을 사용하여 태그 생성
표준 속성, 비공개, 비재귀, 비로버스 및 우선순위가 없는 inherited-enabled로 pthread_mutex_t
오브젝트를 초기화하면 우선순위가 적용되지 않습니다.
절차
다음 중 하나를 사용하여
pthreads
아래에>-< 오브젝트를 생성합니다.-
pthread_mutex_t(my_mutex);
pthread_mutex_init(&my_mutex, &my_mutex_attr);
여기서
&my_mutex_attr;
은 attribute 객체입니다.
-
29.4. 고급 attributes
다음 고급 속성을 태그 특성 개체에 저장할 수 있습니다.
triggerbinding 특성
- 공유 및 개인 태그
공유는 프로세스 간에 사용할 수 있지만 더 많은 오버헤드를 생성할 수 있습니다.
pthread_mutexattr_setpshared(&my_mutex_attr, PTHREAD_PROCESS_SHARED);
- 실시간 우선순위 상속
우선순위 상속을 사용하여 우선 순위 버전 문제를 방지할 수 있습니다.
pthread_mutexattr_setprotocol(&my_mutex_attr, PTHREAD_PRIO_INHERIT);
- 강력한 경우
pthread가 종료되면 pthread 아래의 강력한 prethreades가 해제됩니다. 그러나 이는 높은 오버헤드 비용이 발생합니다. 이 문자열의 _NP 는 이 옵션이 POSIX가 아니거나 이식 가능하지 않음을 나타냅니다.
pthread_mutexattr_setrobust_np(&my_mutex_attr, PTHREAD_MUTEX_ROBUST_NP);
- triggerinitinitialization
그러나 공유는 프로세스 간에 사용할 수 있지만 더 많은 오버헤드를 만들 수 있습니다.
pthread_mutex_init(&my_mutex_attr, &my_mutex);
29.5. CloudEvent 특성 오브젝트 정리
10.0.0.1 특성 개체를 사용하여 만든 후에는 특성 개체를 유지하여 동일한 형식의 더 많은 device를 초기화하거나 정리할 수 있습니다.After theECDHE has been created using theECDHE attribute object, you can keep the attribute object to initialize more of the same type, or you can clean it up. 두 경우 모두 영향을 받지 않습니다.
절차
_destroy
명령을 사용하여 속성 오브젝트를 정리합니다.pthread_mutexattr_destroy(&my_mutex_attr);
이제 CloudEvent는 일반 pthread_mutex 로 작동하며 정상적으로 잠기고 잠금 해제 및 삭제할 수 있습니다.
29.6. 추가 리소스
-
futex(7)
man page -
pthread_mutex_destroy(P)
매뉴얼 페이지 -
pthread_mutexattr_setprotocol(3p)
man page -
pthread_mutexattr_setprioceiling(3p)
man page
30장. 애플리케이션 성능 분석
per
f는 성능 분석 도구입니다. 간단한 명령줄 인터페이스를 제공하며 Linux 성능 측정에서 CPU 하드웨어 차이를 추상화합니다. per
f는 커널이 내보낸 perf_events
인터페이스를 기반으로 합니다.
perf
의 한 가지 장점은 커널과 아키텍처 둘 다라는 것입니다. 분석 데이터는 특정 시스템 구성 없이도 검토할 수 있습니다.
사전 요구 사항
-
perf
패키지가 시스템에 설치되어 있어야 합니다. - 관리자 권한이 있어야 합니다.
30.1. 시스템 전체 통계 수집
perf record
명령은 시스템 전체 통계를 수집하는 데 사용됩니다. 모든 프로세서에서 사용할 수 있습니다.
절차
시스템 전체 성능 통계를 수집합니다.
# perf record -a ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.725 MB perf.data (~31655 samples) ]
이 예에서 모든 CPU는
-a
옵션으로 표시되고 프로세스는 몇 초 후에 종료되었습니다. 결과는 0.725MB의 데이터를 수집하여 새로 생성된perf.data
파일에 저장했습니다.
검증
결과 파일이 생성되었는지 확인합니다.
# ls perf.data
30.2. 성능 분석 결과 보관
perf archive
명령을 사용하여 다른 시스템에서 perf
의 perf 결과를 분석할 수 있습니다. 다음의 경우 필요하지 않을 수 있습니다.
-
바이너리 및 라이브러리와 같은 동적 공유 오브젝트(DSO)는 이미
~/.debug/
캐시와 같은 분석 시스템에 있습니다. - 두 시스템에는 동일한 바이너리 세트가 있습니다.
절차
perf
명령의 결과 아카이브를 만듭니다.# perf archive
아카이브에서 tarball을 만듭니다.
# tar cvf perf.data.tar.bz2 -C ~/.debug
30.3. 성능 분석 결과 분석
이제 perf 레코드
기능의 데이터를 perf report
명령을 사용하여 직접 조사할 수 있습니다.
절차
결과를
perf.data
파일 또는 아카이브된 tarball에서 직접 분석합니다.# perf report
보고서의 출력은 애플리케이션의 최대 CPU 사용량에 따라 정렬됩니다. 이는 프로세스의 커널 또는 사용자 공간에서 샘플이 발생했는지를 나타냅니다.
이 보고서는 샘플이 가져온 모듈에 대한 정보를 보여줍니다.
-
커널 모듈에서 발생하지 않은 커널 샘플은 표기법
[kernel.kallsyms]
으로 표시됩니다. -
커널 모듈에서 발생한 커널 샘플은
[module]
,[ext4]
로 표시됩니다. 사용자 공간의 프로세스의 경우 결과에 해당 프로세스와 연결된 공유 라이브러리가 표시될 수 있습니다.
보고서는 프로세스가 커널 또는 사용자 공간에서도 발생하는지 여부를 나타냅니다.
-
결과
[.]
는 사용자 공간을 나타냅니다. -
결과
[k]
는 커널 공간을 나타냅니다.
숙련된
perf
개발자에게 적합한 데이터를 포함하여 보다 세분화된 세부 정보를 검토할 수 있습니다.-
커널 모듈에서 발생하지 않은 커널 샘플은 표기법
30.4. 사전 정의된 이벤트 나열
하드웨어 추적 지점 활동을 가져올 수 있는 다양한 옵션이 있습니다.
절차
사전 정의된 하드웨어 및 소프트웨어 이벤트를 나열합니다.
# perf list List of pre-defined events (to be used in -e): cpu-cycles OR cycles [Hardware event] stalled-cycles-frontend OR idle-cycles-frontend [Hardware event] stalled-cycles-backend OR idle-cycles-backend [Hardware event] instructions [Hardware event] cache-references [Hardware event] cache-misses [Hardware event] branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] cpu-clock [Software event] task-clock [Software event] page-faults OR faults [Software event] minor-faults [Software event] major-faults [Software event] context-switches OR cs [Software event] cpu-migrations OR migrations [Software event] alignment-faults [Software event] emulation-faults [Software event] ...[output truncated]...
30.5. 지정된 이벤트에 대한 통계 가져오기
perf stat
명령을 사용하여 특정 이벤트를 볼 수 있습니다.
절차
perf stat
기능을 사용하여 컨텍스트 전환 수를 확인합니다.# perf stat -e context-switches -a sleep 5 ^Performance counter stats for 'sleep 5': 15,619 context-switches 5.002060064 seconds time elapsed
결과는 5초, 15619 컨텍스트 전환이 발생했음을 보여줍니다.
스크립트를 실행하여 파일 시스템 활동을 봅니다. 다음은 예제 스크립트입니다.
# for i in {1..100}; do touch /tmp/$i; sleep 1; done
다른 터미널에서
perf stat
명령을 실행합니다.# perf stat -e ext4:ext4_request_inode -a sleep 5 Performance counter stats for 'sleep 5': 5 ext4:ext4_request_inode 5.002253620 seconds time elapsed
결과는 스크립트에서 5개의 파일을 생성하도록 요청하여 5개의
inode
요청이 있음을 나타내는 메시지를 표시한 것으로 표시됩니다.
30.6. 추가 리소스
-
Perf helpCOMM AND
-
perf
(1) 매뉴얼 페이지
31장. stress-ng를 사용하여 실시간 시스템을 테스트하는 응력 테스트
강조 표시는
시스템의 기능을 측정하여 불합리한 조건에서 적절한 수준의 효율성을 유지합니다. stress-ng
툴은 모든 커널 인터페이스를 로드하고 과부하할 수 있는 stress 워크로드 생성기입니다. 여기에는 스트레스 요인으로 알려진 광범위한 응력 메커니즘이 포함되어 있습니다. 과부하 테스트는 시스템이 과도하게 작동할 때 발생하는 열 오버런 및 운영 체제 버그와 같은 머신 작업 및 트립 하드웨어 문제를 만듭니다.
1000개 이상의 다양한 테스트가 있습니다. 여기에는 부동 소수점, 정수, 비트 조작, 제어 흐름 및 가상 메모리 테스트를 실행하는 CPU 특정 테스트가 포함됩니다.
테스트 중 일부가 잘못 설계 된 하드웨어에서 시스템의 열 영역 이동 지점에 영향을 줄 수 있으므로 강조
표시 된 도구를 사용하십시오. 이로 인해 시스템 성능에 영향을 미치고 과도한 시스템 제한으로 인해 중단하기 어려울 수 있습니다.
31.1. CPU 부동 소수점 단위 및 프로세서 데이터 캐시 테스트
부동 소수점 단위는 부동 소수점 연산을 수행하는 프로세서의 기능 부분입니다.A floating-point unit is the functional part of the processor that performs floating-point arithmetic operations. 부동 소수점 단위는 수치화 작업을 처리하고 부동 숫자 또는 10진수 계산을 더 간단하게 만듭니다.
--matrix-method
옵션을 사용하면 CPU 부동 소수점 작업 및 프로세서 데이터 캐시를 테스트하는 데 어려움을 겪을 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있어야 합니다.
절차
한 CPU에서 60초 동안 부동 소수점을 테스트하려면
--matrix
옵션을 사용합니다.# stress-ng --matrix 1 -t 1m
60초 동안 두 개 이상의 CPU에서 여러 리모터를 실행하려면
--times
또는-t
옵션을 사용합니다.# stress-ng --matrix 0 -t 1m stress-ng --matrix 0 -t 1m --times stress-ng: info: [16783] dispatching hogs: 4 matrix stress-ng: info: [16783] successful run completed in 60.00s (1 min, 0.00 secs) stress-ng: info: [16783] for a 60.00s run time: stress-ng: info: [16783] 240.00s available CPU time stress-ng: info: [16783] 205.21s user time ( 85.50%) stress-ng: info: [16783] 0.32s system time ( 0.13%) stress-ng: info: [16783] 205.53s total time ( 85.64%) stress-ng: info: [16783] load average: 3.20 1.25 1.40
stressors가 0인 특수 모드에서는 실행할 사용 가능한 CPU를 쿼리하여 CPU 번호를 지정할 필요가 없습니다.
필요한 총 CPU 시간은 4 x 60 초 (240 초)입니다.이 중 0.13 %는 사용자 시간에 85.50%이며,
stress-ng
는 모든 CPU의 85.64 %를 실행합니다.POSIX 메시지 큐를 사용하여 프로세스 간 메시지 전달을 테스트하려면
-mq
옵션을 사용합니다.# stress-ng --mq 0 -t 30s --times --perf
mq
옵션은 POSIX 메시지 큐를 사용하여 컨텍스트 전환을 강제 적용하도록 특정 수의 프로세스를 구성합니다. 이 워크로드 테스트는 낮은 데이터 캐시 누락을 목표로 합니다.
31.2. 여러 강조 메커니즘으로 CPU 테스트
stress-ng
툴은 여러 개의 stress 테스트를 실행합니다. 기본 모드에서는 지정된 stressor 메커니즘을 병렬로 실행합니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있어야 합니다.
절차
다음과 같이 CPU 강조 표시기 인스턴스를 여러 개 실행합니다.
# stress-ng --cpu 2 --matrix 1 --mq 3 -t 5m
예를 들어,
stress-ng
는 CPU 강조기의 두 개의 인스턴스, 즉 매트릭스 강조기 인스턴스 한 개와 메시지 대기열 강조기의 인스턴스 3개로 5분 동안 테스트할 수 있습니다.모든 stress 테스트를 병렬로 실행하려면
-all
옵션을 사용합니다.# stress-ng --all 2
이 예에서
stress-ng
는 모든 과부하 테스트의 두 인스턴스를 병렬로 실행합니다.특정 순서로 서로 다른 각 강조표를 실행하려면
--seq
옵션을 사용합니다.# stress-ng --seq 4 -t 20
이 예에서,
stress-ng
는 모든 스트레스를 1분 20분 동안 실행하며, 각 강조기의 인스턴스 수는 온라인 CPU 수와 일치합니다.테스트 실행에서 특정 과부하를 제외하려면
-x
옵션을 사용합니다.# stress-ng --seq 1 -x numa,matrix,hdd
이 예에서
stress-ng
는numa
,hdd
및주요
과부하 메커니즘을 제외하고 각각의 한 인스턴스인 모든 스트레스를 실행합니다.
31.3. CPU heat 생성 측정
CPU heat 생성을 측정하기 위해 지정된 응력기는 짧은 기간 동안 높은 온도를 생성하여 최대 heat 생성 시 시스템의 번화 신뢰성과 안정성을 테스트합니다. --matrix-size
옵션을 사용하면 짧은 기간 동안 Celsius도 CPU 온도를 측정할 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
지정된 기간 동안 높은 온도에서 CPU 동작을 테스트하려면 다음 명령을 실행합니다.
# stress-ng --matrix 0 --matrix-size 64 --tz -t 60 stress-ng: info: [18351] dispatching hogs: 4 matrix stress-ng: info: [18351] successful run completed in 60.00s (1 min, 0.00 secs) stress-ng: info: [18351] matrix: stress-ng: info: [18351] x86_pkg_temp 88.00 °C stress-ng: info: [18351] acpitz 87.00 °C
이 예에서
stress-ng
는 프로세서 패키지 열 영역을 60초 동안 88도에 도달하도록 구성합니다.(선택 사항) 실행 마지막에 보고서를 인쇄하려면
--tz
옵션을 사용합니다.# stress-ng --cpu 0 --tz -t 60 stress-ng: info: [18065] dispatching hogs: 4 cpu stress-ng: info: [18065] successful run completed in 60.07s (1 min, 0.07 secs) stress-ng: info: [18065] cpu: stress-ng: info: [18065] x86_pkg_temp 88.75 °C stress-ng: info: [18065] acpitz 88.38 °C
31.4. bogo 작업을 통해 테스트 결과 측정
stress-ng
툴은 초당 bogo 작업을 측정하여 대기 테스트 처리량을 측정할 수 있습니다. bogo 작업의 크기는 강조 표시 상태에 따라 다릅니다. 테스트 결과는 정확하지 않지만 성능의 대략적인 추정치를 제공합니다.
이 측정을 정확한 벤치마크 지표로 사용해서는 안 됩니다. 이러한 추정치는 서로 다른 커널 버전 또는 과부하를 구축하는 데 사용되는 다른 컴파일러 버전에서 시스템 성능 변경 사항을 이해하는 데 도움이 됩니다
. --metrics-brief
옵션을 사용하여 시스템에서 사용 가능한 전체 bogo 작업과 매트릭스 과부하 성능을 표시합니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
bogo 작업으로 테스트 결과를 측정하려면
--metrics-brief
옵션과 함께 사용합니다.# stress-ng --matrix 0 -t 60s --metrics-brief stress-ng: info: [17579] dispatching hogs: 4 matrix stress-ng: info: [17579] successful run completed in 60.01s (1 min, 0.01 secs) stress-ng: info: [17579] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s stress-ng: info: [17579] (secs) (secs) (secs) (real time) (usr+sys time) stress-ng: info: [17579] matrix 349322 60.00 203.23 0.19 5822.03 1717.25
--metrics-brief
옵션은매트릭스
테이너가 60초 동안 실행하는 테스트 결과 및 총 실시간 bogo 작업을 표시합니다.
31.5. 가상 메모리 부족 생성
메모리 부족이 있을 때 커널은 스왑에 페이지 쓰기를 시작합니다. --page-in
옵션을 사용하여 가상 메모리를 과부하시켜 비동시 페이지가 가상 메모리로 다시 스왑되도록 강제할 수 있습니다. 이로 인해 가상 시스템이 크게 실행됩니다. --page-in
옵션을 사용하면 bigheap
,mmap
및 가상 머신(vm
) 과부하 요인에 대해 이 모드를 활성화할 수 있습니다. --page-in
옵션, 코어가 아닌 할당된 페이지를 눌러 의 페이지로 강제 적용합니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
가상 메모리를 테스트하도록 하려면
--page-in
옵션을 사용합니다.# stress-ng --vm 2 --vm-bytes 2G --mmap 2 --mmap-bytes 2G --page-in
이 예에서는 할당된 버퍼 크기, 2 x 2GB의
vm
stressor 및--page
기보다 작은 메모리가 4GB인 시스템에서 메모리 부족을 테스트합니다.-in
이 활성화된 2 x 2GB의mmap
강조
31.6. 장치에서 대규모 인터럽트 로드 테스트
높은 빈도에서 타이머 실행은 대규모 인터럽트 로드를 생성할 수 있습니다. 적절하게 선택된 타이머 주파수를 가진 -timer
stressor는 초당 많은 인터럽트를 강제할 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
인터럽트 로드를 생성하려면
--timer
옵션을 사용합니다.# stress-ng --timer 32 --timer-freq 1000000
이 예에서는
stress-ng
테스트 32개의 인스턴스 1ECDHE를 테스트합니다.
31.7. 프로그램에서 주요 페이지 폴트 생성
stress-ng
를 사용하면 메모리에 로드되지 않은 주요 페이지 폴트를 생성하여 페이지 폴트 속도를 테스트하고 분석할 수 있습니다. 새 커널 버전에서 userfaultfd
메커니즘은 프로세스의 가상 메모리 레이아웃에서 페이지 폴트에 대한 스레드를 찾는 오류를 알립니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
초기 커널 버전에서 주요 페이지 폴트를 생성하려면 다음을 사용합니다.
# stress-ng --fault 0 --perf -t 1m
새 커널 버전에서 주요 페이지 폴트를 생성하려면 다음을 사용합니다.
# stress-ng --userfaultfd 0 --perf -t 1m
31.8. CPU 과부하 테스트 메커니즘 보기
CPU 강조 표시 테스트에는 CPU를 실행하는 방법이 포함되어 있습니다. which
옵션을 사용하여 모든 방법을 볼 수 있도록 출력을 출력할 수 있습니다.
기본적으로 테스트 방법을 지정하지 않으면 stressor는 라운드 로빈 방식으로 모든 과부하를 확인하여 각 부하에 대해 CPU를 테스트합니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
사용 가능한 모든 stressor 메커니즘을 출력하고 다음 옵션을 사용합니다.
# stress-ng --cpu-method which cpu-method must be one of: all ackermann bitops callfunc cdouble cfloat clongdouble correlate crc16 decimal32 decimal64 decimal128 dither djb2a double euler explog fft fibonacci float fnv1a gamma gcd gray hamming hanoi hyperbolic idct int128 int64 int32
--cpu-method
옵션을 사용하여 특정 CPU 과부하 방법을 지정합니다.# stress-ng --cpu 1 --cpu-method fft -t 1m
31.9. 확인 모드 사용
검증
모드는 테스트가 활성화될 때 결과를 검증합니다. 테스트 실행의 메모리 콘텐츠를 확인하고 예기치 않은 오류를 보고합니다.
모든 오버로드는 확인
모드가 없으며 활성화로 인해 이 모드에서 추가 확인 단계가 실행되므로 bogo 작업 통계를 줄일 수 있습니다.
사전 요구 사항
- 시스템에 대한 root 권한이 있습니다.
절차
stress 테스트 결과를 확인하려면
--verify
옵션을 사용합니다.# stress-ng --vm 1 --vm-bytes 2G --verify -v
이 예에서
stress-ng
는--verify
모드로 구성된vm
stressor를 사용하여 실질적으로 매핑된 메모리에 대한 완전한 메모리 검사 출력을 출력합니다. 메모리의 읽기 및 쓰기 결과를 확인합니다.Checks the read and write results on the memory.
32장. 컨테이너 생성 및 실행
이 섹션에서는 실시간 커널로 컨테이너 생성 및 실행에 대한 정보를 제공합니다.
사전 요구 사항
-
podman
및 기타 컨테이너 관련 유틸리티를 설치합니다. - RHEL 8의 Linux 컨테이너 관리 및 관리에 대해 알아보십시오.
-
kernel-rt
패키지 및 기타 실시간 관련 패키지를 설치합니다.
32.1. 컨테이너 생성
실시간 커널과 기본 RHEL 커널 모두에서 다음 옵션을 모두 사용할 수 있습니다. kernel-rt
패키지는 잠재적인 결정성을 개선하고 일반적인 문제 해결을 허용합니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
다음 절차에서는 실시간 커널과 관련하여 Linux 컨테이너를 구성하는 방법을 설명합니다.
컨테이너에 사용할 디렉터리를 만듭니다. 예를 들면 다음과 같습니다.
# mkdir cyclictest
해당 디렉터리로 변경합니다.
# cd cyclictest
컨테이너 레지스트리 서비스를 제공하는 호스트에 로그인합니다.
# podman login registry.redhat.io Username: my_customer_portal_login Password: *** Login Succeeded!
레지스트리 호스트에 로그인하는 방법에 대한 자세한 내용은 컨테이너 빌드, 실행 및 관리를 참조하십시오.
다음 Dockerfile을 생성합니다.
# vim Dockerfile FROM rhel8 RUN subscription-manager repos --enable=rhel-8-for-x86_64-rt-rpm RUN dnf -y install rt-tests ENTRYPOINT cyclictest --smp -p95
Dockerfile이 포함된 디렉터리에서 컨테이너 이미지를 빌드합니다.
# podman build -t cyclictest .
32.2. 컨테이너 실행
Dockerfile로 빌드된 컨테이너를 실행할 수 있습니다.
절차
podman run
명령을 사용하여 컨테이너를 실행합니다.# podman run --device=/dev/cpu_dma_latency --cap-add ipc_lock --cap-add sys_nice --cap-add sys_rawio --rm -ti cyclictest /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.08 0.10 0.09 2/947 15 T: 0 ( 8) P:95 I:1000 C: 3209 Min: 1 Act: 1 Avg: 1 Max: 14 T: 1 ( 9) P:95 I:1500 C: 2137 Min: 1 Act: 2 Avg: 1 Max: 23 T: 2 (10) P:95 I:2000 C: 1601 Min: 1 Act: 2 Avg: 2 Max: 7 T: 3 (11) P:95 I:2500 C: 1280 Min: 1 Act: 2 Avg: 2 Max: 72 T: 4 (12) P:95 I:3000 C: 1066 Min: 1 Act: 1 Avg: 1 Max: 7 T: 5 (13) P:95 I:3500 C: 913 Min: 1 Act: 2 Avg: 2 Max: 87 T: 6 (14) P:95 I:4000 C: 798 Min: 1 Act: 1 Avg: 2 Max: 7 T: 7 (15) P:95 I:4500 C: 709 Min: 1 Act: 2 Avg: 2 Max: 29
이 예에서는 필요한 실시간 관련 옵션이 있는 podman run
명령을 보여줍니다. 예를 들면 다음과 같습니다.
-
첫 번째(FIFO) 스케줄러 정책은
--cap-add=sys_nice
옵션을 통해 컨테이너 내부에서 실행되는 워크로드에 사용할 수 있습니다. 이 옵션을 사용하면 실시간 워크로드를 튜닝할 때 다른 중요한 구성 차원인 스레드의 CPU 선호도를 설정할 수도 있습니다. --device=/dev/cpu_dma_latency
옵션은 컨테이너 내에서 호스트 장치를 사용할 수 있도록 합니다(하위적으로 CPU 유휴 시간 관리를 구성하기 위해cyclictest 워크로드에서 사용). 지정된 장치를 사용할 수 없는 경우 아래 메시지와 유사한 오류가 표시됩니다.WARN: stat /dev/cpu_dma_latency failed: No such file or directory
이와 같은 오류 메시지로 인해 문제가 발생하는 경우 podman-run(1) 매뉴얼 페이지를 참조하십시오. 컨테이너 내에서 특정 워크로드를 실행하려면 다른
podman-run
옵션이 유용할 수 있습니다./dev/cpu/*/msr
와 같은 CPU 장치 파일을 매핑하려면--device=/dev/cpu
옵션을 추가하여 디렉터리 계층 구조를 추가해야 하는 경우도 있습니다.
32.3. 추가 리소스
33장. 프로세스의 우선 순위 표시
sched_getattr
특성을 사용하여 프로세스의 스케줄링 정책에 대한 정보와 프로세스의 우선 순위에 대한 정보를 표시할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
33.1. chrt 유틸리티
chrt
유틸리티는 스케줄러 정책 및 우선순위를 확인하고 조정합니다. 원하는 속성을 사용하여 새 프로세스를 시작하거나 실행 중인 프로세스의 속성을 변경할 수 있습니다.
추가 리소스
-
chrt(1)
매뉴얼 페이지
33.2. chrt 유틸리티를 사용하여 프로세스 우선 순위 표시
지정된 프로세스의 현재 스케줄링 정책 및 스케줄링 우선 순위를 표시할 수 있습니다.
절차
실행 중인 프로세스를 지정하여
-p
옵션을 사용하여chrt
유틸리티를 실행합니다.# chrt -p 468 pid 468's current scheduling policy: SCHED_FIFO pid 468's current scheduling priority: 85 # chrt -p 476 pid 476's current scheduling policy: SCHED_OTHER pid 476's current scheduling priority: 0
33.3. sched_getscheduler()를 사용하여 프로세스 우선 순위 표시
실시간 프로세스는 일련의 함수를 사용하여 정책 및 우선 순위를 제어합니다. sched_getscheduler()
함수를 사용하여 지정된 프로세스에 대한 스케줄러 정책을 표시할 수 있습니다.
절차
get_sched.c
소스 파일을 생성하고 텍스트 편집기에서 엽니다.$ {EDITOR} get_sched.c
다음 줄을 파일에 추가합니다.
#include <sched.h> #include <unistd.h> #include <stdio.h> int main() { int policy; pid_t pid = getpid(); policy = sched_getscheduler(pid); printf("Policy for pid %ld is %i.\n", (long) pid, policy); return 0; }
정책
변수에는 지정된 프로세스에 대한 스케줄러 정책이 있습니다.프로그램을 컴파일합니다.
$ gcc get_sched.c -o get_sched
다양한 정책과 함께 프로그램을 실행합니다.
$ chrt -o 0 ./get_sched Policy for pid 27240 is 0. $ chrt -r 10 ./get_sched Policy for pid 27243 is 2. $ chrt -f 10 ./get_sched Policy for pid 27245 is 1.
추가 리소스
-
sched_getscheduler(2)
man page
33.4. 스케줄러 정책의 유효한 범위 표시
sched_get_priority_min()
및 sched_get_priority_max()
함수를 사용하여 지정된 스케줄러 정책에 유효한 우선순위 범위를 확인할 수 있습니다.
절차
sched_get.c
소스 파일을 생성하고 텍스트 편집기에서 엽니다.$ {EDITOR} sched_get.c
파일에 다음을 입력합니다.
#include <stdio.h> #include <unistd.h> #include <sched.h> int main() { printf("Valid priority range for SCHED_OTHER: %d - %d\n", sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER)); printf("Valid priority range for SCHED_FIFO: %d - %d\n", sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO)); printf("Valid priority range for SCHED_RR: %d - %d\n", sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR)); return 0; }
참고지정된 스케줄러 정책을 시스템에서 알 수 없는 경우 함수는
-1
을 반환하고errno
는EINVAL
로 설정됩니다.참고ScanSetting
_FIFO
및 10.0.0.1_RR
모두1
에서99
사이의 범위 내의 숫자일 수 있습니다. POSIX는 이 범위를 충족하기 위해 보장되지 않으며 이식 가능한 프로그램은 이러한 기능을 사용해야 합니다.- 파일을 저장하고 편집기를 종료합니다.
프로그램을 컴파일합니다.
$ gcc sched_get.c -o msched_get
이제 sched_get
프로그램이 준비되었으며 저장된 디렉터리에서 실행할 수 있습니다.
추가 리소스
-
sched_get_priority_min(2)
man page -
sched_get_priority_max(2)
man page
33.5. 프로세스의 timeslice 표시
ScanSetting _RR
(round-robin) 정책은 10.0.0.1 _FIFO
(first-in, first-out) 정책과 약간 다릅니다. gRPC_RR
은 라운드 로빈 회전에서 우선 순위가 동일한 동시 프로세스를 할당합니다. 이러한 방식으로 각 프로세스에 timeslice가 할당됩니다. sched_rr_get_interval()
함수는 각 프로세스에 할당된 timeslice를 보고합니다.
POSIX를 사용하려면 이 함수가 10.0.0.1 _RR 스케줄러 정책으로 실행되도록 구성된 프로세스에서만 작동해야 하지만
함수는 Linux의 모든 프로세스의 timeslice 길이를 검색할 수 있습니다.
sched_
rr_get_get_interval()
timeslice 정보는 timespec
으로 반환됩니다. 이것은 00:00:00 GMT의 기본 시간, 1970년 1월 1일 이후의 초 및 나노초 수입니다.
struct timespec { time_t tv_sec; /* seconds / long tv_nsec; / nanoseconds */ };
절차
sched_timeslice.c
소스 파일을 생성하고 텍스트 편집기에서 엽니다.$ {EDITOR} sched_timeslice.c
sched_timeslice.c
파일에 다음 행을 추가합니다.#include <stdio.h> #include <sched.h> int main() { struct timespec ts; int ret; /* real apps must check return values */ ret = sched_rr_get_interval(0, &ts); printf("Timeslice: %lu.%lu\n", ts.tv_sec, ts.tv_nsec); return 0; }
- 파일을 저장하고 편집기를 종료합니다.
프로그램을 컴파일합니다.
$ gcc sched_timeslice.c -o sched_timeslice
다양한 정책 및 우선 순위로 프로그램을 실행합니다.
$ chrt -o 0 ./sched_timeslice Timeslice: 0.38994072 $ chrt -r 10 ./sched_timeslice Timeslice: 0.99984800 $ chrt -f 10 ./sched_timeslice Timeslice: 0.0
추가 리소스
-
nice(2)
man page -
getpriority(2)
man page -
setpriority(2)
매뉴얼 페이지
33.6. 프로세스의 스케줄링 정책 및 관련 속성 표시
sched_getattr()
함수는 PID로 식별되는 지정된 프로세스에 현재 적용되는 스케줄링 정책을 쿼리합니다. PID가 0이면 호출 프로세스의 정책이 검색됩니다.
size
인수는 사용자 공간에 알려진 sched_attr
구조의 크기를 반영해야 합니다. 커널은 sched_attr::size
를 sched_attr
구조의 크기로 채웁니다.
입력 구조가 작은 경우 커널은 제공된 공간 외부의 값을 반환합니다. 그 결과 시스템 호출이 E2BIG
오류와 함께 실패합니다. 다른 sched_attr
필드는 The sched_attr 구조에 설명된 대로 채워집니다.
절차
sched_timeslice.c
소스 파일을 생성하고 텍스트 편집기에서 엽니다.$ {EDITOR} sched_timeslice.c
sched_timeslice.c
파일에 다음 행을 추가합니다.#define _GNU_SOURCE #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <linux/unistd.h> #include <linux/kernel.h> #include <linux/types.h> #include <sys/syscall.h> #include <pthread.h> #define gettid() syscall(__NR_gettid) #define SCHED_DEADLINE 6 /* XXX use the proper syscall numbers */ #ifdef __x86_64__ #define __NR_sched_setattr 314 #define __NR_sched_getattr 315 #endif struct sched_attr { __u32 size; __u32 sched_policy; __u64 sched_flags; /* SCHED_NORMAL, SCHED_BATCH */ __s32 sched_nice; /* SCHED_FIFO, SCHED_RR */ __u32 sched_priority; /* SCHED_DEADLINE (nsec) */ __u64 sched_runtime; __u64 sched_deadline; __u64 sched_period; }; int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int size, unsigned int flags) { return syscall(__NR_sched_getattr, pid, attr, size, flags); } int main (int argc, char **argv) { struct sched_attr attr; unsigned int flags = 0; int ret; ret = sched_getattr(0, &attr, sizeof(attr), flags); if (ret < 0) { perror("sched_getattr"); exit(-1); } printf("main thread pid=%ld\n", gettid()); printf("main thread policy=%ld\n", attr.sched_policy); printf("main thread nice=%ld\n", attr.sched_nice); printf("main thread priority=%ld\n", attr.sched_priority); printf("main thread runtime=%ld\n", attr.sched_runtime); printf("main thread deadline=%ld\n", attr.sched_deadline); printf("main thread period=%ld\n", attr.sched_period); return 0; }
sched_timeslice.c
파일을 컴파일합니다.$ gcc sched_timeslice.c -o sched_timeslice
sched_timeslice
프로그램의 출력을 확인합니다.$ ./sched_timeslice main thread pid=321716 main thread policy=6 main thread nice=0 main thread priority=0 main thread runtime=1000000 main thread deadline=9000000 main thread period=10000000
33.7. sched_attr 구조
sched_attr
구조에는 지정된 스레드에 대한 스케줄링 정책 및 관련 속성을 포함하거나 정의합니다. sched_attr
구조의 형식은 다음과 같습니다.
struct sched_attr { u32 size; u32 sched_policy u64 sched_flags s32 sched_nice u32 sched_priority /* SCHED_DEADLINE fields */ u64 sched_runtime u64 sched_deadline u64 sched_period };
sched_attr 데이터 구조
- 크기
스레드 크기(바이트)입니다. 구조의 크기가 커널 구조보다 작으면 추가 필드가
0
으로 가정합니다. 크기가 커널 구조보다 크면 커널은 모든 추가 필드를0
으로 확인합니다.참고sched_setattr()
함수가 커널 구조보다 크고 커널 구조의 크기를 업데이트하는 경우E2BIG
오류와 함께 실패합니다.- sched_policy
- 스케줄링 정책
- sched_flags
fork()
함수를 사용하여 프로세스 포크가 시작될 때 스케줄링 동작을 제어할 수 있습니다. 호출 프로세스를 상위 프로세스라고 하며 새 프로세스를 하위 프로세스라고 합니다. 유효한 값은 다음과 같습니다.-
0
: 하위 프로세스는 상위 프로세스의 스케줄링 정책을 상속합니다. -
gRPC_FLAG_RESET_ON_FORK: fork
(): 하위 프로세스는 상위 프로세스에서 스케줄링 정책을 상속하지 않습니다. 대신 기본 스케줄링 정책(struct sched_attr){ .sched_policy =ECDHE_OTHER, }
로 설정됩니다.
-
- sched_nice
-
CloudEvent
_OTHER 또는 ScanSetting
스케줄링 정책을 사용할 때 설정할_
BATCH좋은
값을 지정합니다.nice
값은-20
(High priority)에서+19
(Low priority) 사이의 범위 범위입니다. - sched_priority
-
10.0.0.1
_FIFO 또는 10.0.0.1
때 설정할 정적 우선 순위를 지정합니다. 다른 정책의 경우 priority를_RR
을 예약할0
으로 지정합니다.
deadline _DEADLINE
필드는 데드라인 예약에만 지정해야 합니다.
-
sched_runtime: 데드라인 스케줄링에 대한
런타임
매개변수를 지정합니다. 값은 나노초 단위로 표시됩니다. -
gRPC_DEADLINE: 데드라인 스케줄링에 대한
데드라인
매개변수를 지정합니다. 값은 나노초 단위로 표시됩니다. -
sched_period: 데드라인 스케줄링의
period
매개변수를 지정합니다. 값은 나노초 단위로 표시됩니다.
34장. 선점 상태 보기
CPU를 사용하는 프로세스는 사용 중인 CPU를 자발적으로 또는 자발적으로 포기할 수 있습니다.
34.1. 선점
프로세스는 완료되면 또는 디스크의 데이터, 키 누름 또는 네트워크 패킷과 같은 이벤트를 대기 중이므로 CPU를 자발적으로 산출할 수 있습니다.
또한 프로세스는 자발적으로 CPU를 산출할 수 있습니다. 이를 선점이라고 하며 더 높은 우선 순위 프로세스에서 CPU를 사용하려는 경우 발생합니다.
선점은 시스템 성능에 특히 부정적인 영향을 미칠 수 있으며 지속적인 선점으로 인해 스래싱으로 알려진 상태가 발생할 수 있습니다. 이 문제는 프로세스가 지속적으로 선점되고 완료까지 프로세스가 실행되지 않을 때 발생합니다.
작업의 우선 순위를 변경하면 일시적인 선점을 줄이는 데 도움이 될 수 있습니다.
34.2. 프로세스의 선점 상태 확인
지정된 프로세스에 대해 자발적으로 및 자발적으로 제공하는 선점 상태를 확인할 수 있습니다. 상태는 /proc/PID/status
에 저장됩니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
절차
/proc/PID/status
의 내용을 표시합니다. 여기서PID
는 프로세스의 ID입니다. 다음은 PID 1000이 있는 프로세스의 선점 상태를 표시합니다.# grep voluntary /proc/1000/status voluntary_ctxt_switches: 194529 nonvoluntary_ctxt_switches: 195338
35장. chrt 유틸리티를 사용하여 프로세스의 우선 순위 설정
chrt
유틸리티를 사용하여 프로세스의 우선 순위를 설정할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
35.1. chrt 유틸리티를 사용하여 프로세스 우선 순위 설정
chrt
유틸리티는 스케줄러 정책 및 우선순위를 확인하고 조정합니다. 원하는 속성을 사용하여 새 프로세스를 시작하거나 실행 중인 프로세스의 속성을 변경할 수 있습니다.
절차
프로세스의 스케줄링 정책을 설정하려면 적절한 명령 옵션 및 매개변수를 사용하여
chrt
명령을 실행합니다. 다음 예에서 명령에 영향을 받는 프로세스 ID는1000
개이며 우선순위(-p
)는50
입니다.# chrt -f -p 50 1000
지정된 스케줄링 정책 및 우선 순위로 애플리케이션을 시작하려면 애플리케이션 이름과 필요한 경우 속성과 함께 애플리케이션을 추가합니다.
# chrt -r -p 50 /bin/my-app
chrt
유틸리티 옵션에 대한 자세한 내용은 chrt 유틸리티 옵션을 참조하십시오.
35.2. chrt 유틸리티 옵션
chrt
유틸리티 옵션에는 명령의 프로세스 및 우선 순위를 지정하는 명령 옵션 및 매개변수가 포함되어 있습니다.
정책 옵션
- -f
-
스케줄러 정책을 10.0.0.1
_FIFO
로 설정합니다. - -o
-
스케줄러 정책을 ScanSetting
_OTHER
로 설정합니다. - -r
-
스케줄러 정책을 10.0.0.1
_RR
(round robin)으로 설정합니다. - -d
-
스케줄러 정책을 ScanSetting
_DEADLINE
으로 설정합니다. - -p n
프로세스의 우선 순위를 n 으로 설정합니다.
프로세스를 10.0.0.1_DEADLINE으로 설정하는 경우
런타임
,데드라인
,period
매개변수를 지정해야 합니다.예를 들면 다음과 같습니다.
# chrt -d --sched-runtime 5000000 --sched-deadline 10000000 --sched-period 16666666 0 video_processing_tool
다음과 같습니다.
-
--sched-runtime 5000000
은 나노초의 실행 시간입니다. -
--sched-deadline 10000000
은 나노초 단위의 상대적 기한입니다. -
--sched-period 16666
은 나노초 단위의 기간입니다. -
0
은chrt
명령에 필요한 사용되지 않는 우선 순위의 자리 표시자입니다.
-
35.3. 추가 리소스
-
chrt(1)
매뉴얼 페이지
36장. 라이브러리 호출을 사용하여 프로세스의 우선 순위 설정
chrt
유틸리티를 사용하여 프로세스의 우선 순위를 설정할 수 있습니다.
사전 요구 사항
- 관리자 권한이 있어야 합니다.
36.1. 우선순위 설정 라이브러리 호출
실시간 프로세스는 정책 및 우선 순위를 제어하기 위해 다른 라이브러리 호출 세트를 사용합니다. 다음 라이브러리 호출은 비실시간 프로세스의 우선 순위를 설정하는 데 사용됩니다.
-
nice
-
setpriority
이 함수는 비실시간 프로세스의 좋은 값을 조정합니다. nice
값은 프로세서에서 실행할 준비가 된 비실시간 프로세스 목록을 정렬하는 방법에 대한 스케줄러 제안의 역할을 합니다. 목록의 헤드에 있는 프로세스는 목록의 추가 감소 전에 실행됩니다.
함수를 사용하려면 sched.h
헤더 파일을 포함해야 합니다. 함수의 반환 코드를 항상 확인하십시오.
36.2. 라이브러리 호출을 사용하여 프로세스 우선 순위 설정
스케줄러 정책 및 기타 매개변수는 sched_setscheduler()
함수를 사용하여 설정할 수 있습니다. 현재 실시간 정책에는 하나의 매개변수 sched_priority
가 있습니다. 이 매개변수는 프로세스의 우선 순위를 조정하는 데 사용됩니다.
sched_setscheduler()
함수에는 sched_setscheduler (sched_setscheduler,pid_t pid, int 정책, const struct sched_param *sp)
형식의 매개변수가 필요합니다.
sched_setscheduler(2)
매뉴얼 페이지에는 오류 코드를 포함하여 sched_setscheduler()
의 가능한 모든 반환 값이 나열됩니다.
프로세스 ID가 0이면 sched_setscheduler()
함수가 호출 프로세스에 대해 작동합니다.
다음 코드 발췌에서는 현재 프로세스의 스케줄러 정책을 10.0.0.1 _FIFO
스케줄러 정책으로 설정하고 우선순위를 50
으로 설정합니다.
struct sched_param sp = { .sched_priority = 50 }; int ret; ret = sched_setscheduler(0, SCHED_FIFO, &sp); if (ret == -1) { perror("sched_setscheduler"); return 1; }
36.3. 라이브러리 호출을 사용하여 프로세스 우선순위 매개변수 설정
sched_setparam()
함수는 특정 프로세스의 스케줄링 매개변수를 설정하는 데 사용됩니다. 그런 다음 sched_getparam()
함수를 사용하여 확인할 수 있습니다.
스케줄링 정책만 반환하는 sched_getscheduler()
함수와 달리 sched_getparam()
함수는 지정된 프로세스에 대한 모든 스케줄링 매개변수를 반환합니다.
절차
지정된 실시간 프로세스의 우선 순위를 읽고 다음 코드 발췌를 두 단계로 증가시킵니다.Use the following code excerpt that reads the priority of a given real-time process and increments it by two:
struct sched_param sp; int ret; ret = sched_getparam(0, &sp); sp.sched_priority += 2; ret = sched_setparam(0, &sp);
이 코드가 실제 애플리케이션에서 사용된 경우 함수에서 반환 값을 확인하고 오류를 적절하게 처리해야 합니다.
우선순위 증가에 유의하십시오. 이 예에서와 같이 스케줄러 우선 순위에 2를 지속적으로 추가하면 잘못된 우선순위가 발생할 수 있습니다.
36.4. 프로세스의 스케줄링 정책 및 관련 속성 설정
sched_setattr()
함수는 PID에 지정된 인스턴스 ID에 대한 스케줄링 정책 및 관련 속성을 설정합니다. pid=0인 경우 sched_setattr()
은 호출 스레드의 프로세스 및 속성에서 작동합니다.
절차
-
호출이 작동하는 프로세스 ID와 다음 실시간 스케줄링 정책 중 하나를 지정하여
sched_setattr()
을 호출합니다.
실시간 스케줄링 정책
SCHED_FIFO
- first-in 및 first-out 정책을 예약합니다.
SCHED_RR
- 라운드 로빈 정책을 예약합니다.
SCHED_DEADLINE
- 데드라인 스케줄링 정책을 예약합니다.
Linux는 다음과 같은 비실시간 스케줄링 정책도 지원합니다.
비실시간 스케줄링 정책
SCHED_OTHER
- 표준 라운드 로빈 시간 할당 정책을 예약합니다.
SCHED_BATCH
- 프로세스의 "배치" 스타일 실행을 예약합니다.
SCHED_IDLE
우선 순위가 매우 낮은 백그라운드 작업을 예약합니다.
gRPC_IDLE
은 정적 우선 순위0
에서만 사용할 수 있으며 nice 값은 이 정책에 영향을 미치지 않습니다.이 정책은 매우 낮은 우선 순위로 작업을 실행하기 위한 것입니다. (+19 nice 값보다 낮음 +19 또는 gRPC
_
BATCH
36.5. 추가 리소스
37장. 실시간 커널 및 솔루션 예약
실시간 커널에서의 예약은 경우에 따라 발생할 수 있습니다. 제공된 정보를 사용하면 실시간 커널에서 스케줄링 정책, 스케줄러 제한 및 스레드 중단 상태에 대한 문제와 잠재적인 솔루션을 파악할 수 있습니다.
37.1. 실시간 커널의 스케줄링 정책
실시간 스케줄링 정책은 하나의 주요 특성을 공유합니다. 높은 우선 순위 스레드가 스레드 또는 스레드가 I/O를 잠급거나 수행하여 대기할 때까지 실행됩니다.
Cryostat _RR
의 경우 운영 체제는 실행 중인 스레드를 중단하여 동일한 Cryostat _RR
우선순위의 다른 스레드를 실행할 수 있도록 합니다. 이러한 경우 중 하나에서 더 낮은 우선 순위 스레드가 CPU 시간을 얻을 수 있도록 정책을 정의하는 POSIX
사양에 의해 프로비저닝이 이루어지지 않습니다. 실시간 스레드의 이러한 특성은 지정된 CPU의 100%를 단조하는 애플리케이션을 쉽게 작성할 수 있음을 의미합니다. 그러나 이로 인해 운영 체제에 문제가 발생합니다. 예를 들어 운영 체제는 시스템 전체 및 CPU별 리소스를 모두 관리하는 역할을 하며 주기적으로 이러한 리소스를 설명하는 데이터 구조를 검사하고 해당 리소스를 사용하는 하우스키핑 활동을 수행해야 합니다. 그러나 코어가 Cryostat _FIFO 스레드에 의해
단조되는 경우 하우스키핑 작업을 수행할 수 없습니다. 결국 전체 시스템이 불안정해지고 잠재적으로 충돌할 수 있습니다.
RHEL for Real Time 커널에서 인터럽트 핸들러는 hieradata _FIFO 우선 순위가 있는
스레드로 실행됩니다. 기본 우선순위는 50입니다. 인터럽트 처리기 스레드보다 높은 Cryostat _FIFO
또는 Cryostat _RR
정책이 있는 cpu-hog 스레드는 인터럽트 처리기가 실행되지 않도록 할 수 있습니다. 이로 인해 프로그램이 인터럽트에 의해 전달되는 데이터 신호를 대기하고 실패하게 됩니다.
37.2. 실시간 커널의 스케줄러 제한
실시간 커널에는 실시간 작업에서 사용할 대역폭을 할당할 수 있는 보호 메커니즘이 포함되어 있습니다. 보호 메커니즘을 실시간 스케줄러 제한이라고 합니다.
실시간 제한 메커니즘의 기본값은 실시간 작업에서 CPU 시간의 95%를 사용할 수 있음을 정의합니다. 나머지 5%는 Cryostat _OTHER
및 유사한 스케줄링 정책에서 실행되는 작업과 같이 실시간이 아닌 작업에 사용됩니다. 단일 실시간 작업이 95% CPU 시간 슬롯을 사용하는 경우 해당 CPU의 나머지 실시간 작업이 실행되지 않습니다. 실시간이 아닌 작업만 나머지 5%의 CPU 시간을 사용합니다. 기본값은 다음과 같은 성능에 영향을 미칠 수 있습니다.
- 실시간 작업에는 사용 가능한 최대 95%의 CPU 시간이 있으며 이는 성능에 영향을 미칠 수 있습니다.
- 실시간 작업은 실시간이 아닌 작업을 실행할 수 없으므로 시스템을 잠그지 않습니다.
실시간 스케줄러 제한은 /proc
파일 시스템의 다음 매개변수에 의해 제어됩니다.
/proc/sys/kernel/sched_rt_period_us
매개변수-
CPU 대역폭의 100%
인 Cryo
stat(마이크로초)의 기간을 정의합니다. 기본값은 1,000,000 Cryostats이며 1 초입니다. 마침표 값의 변경 사항은 매우 낮거나 낮으면 문제가 발생할 수 있으므로 신중하게 고려해야 합니다. /proc/sys/kernel/sched_rt_runtime_us
매개변수-
모든 실시간 작업에 사용할 수 있는 총 대역폭을 정의합니다. 기본값은 950,000 Cryostats (0.95 s)이며 이는 CPU 대역폭의 95%입니다. 값을
-1
로 설정하면 최대 100%의 CPU 시간을 사용하도록 실시간 작업이 구성됩니다. 이는 실시간 작업이 잘 엔지니어링되어 바인딩되지 않은 폴링 루프와 같은 명확한 경고 사항이 없는 경우에만 적합합니다.
37.3. 실시간 커널에서 스레드 중단
스레드가 고가용성 임계값보다 긴 CPU 실행 큐에 있고 진행하지 않는 경우 발생합니다. 스레드 중단의 일반적인 원인은 CPU에 바인딩된 Cryostat _FIFO 또는 Cryostat
과 같은 고정 우선 순위의 폴링 애플리케이션을 실행하는 것입니다. 폴링 애플리케이션은 I/O를 차단하지 않으므로 _
RRkworkers
와 같은 다른 스레드가 해당 CPU에서 실행되지 않도록 할 수 있습니다.
스레드 래핑을 줄이기 위한 초기 시도는 실시간 제한으로 호출됩니다. 실시간 제한에서 각 CPU는 비 실시간 작업에 전용 실행 시간의 일부를 갖습니다. 제한의 기본 설정은 실시간 작업에 대해 CPU의 95%를 사용하고 5%는 비실시간 작업을 위해 예약되어 있습니다. 단일 실시간 작업이 있는 경우 결함이 발생하지만 CPU에 할당된 실시간 작업이 여러 개 있는 경우 작동하지 않습니다. 다음을 사용하여 문제를 해결할 수 있습니다.
stalld
메커니즘stalld
메커니즘은 실시간 제한의 대안이며 일부 제한 결함을 피할 수 있습니다.stalld
는 시스템의 각 스레드 상태를 주기적으로 모니터링하는 데몬이며 실행 큐에 있는 스레드를 실행하지 않고 지정된 시간 동안 실행되는 스레드를 찾습니다.stalld
는 thread가 Cryostat_DEADLINE
정책을 사용하도록 일시적으로 변경되고 지정된 CPU에서 스레드에 작은 시간을 할당합니다. 그런 다음 스레드가 실행되고 time 슬라이스를 사용하면 스레드가 원래 스케줄링 정책으로 돌아가 스레드 상태를 계속 모니터링합니다.하우스키핑 CPU는 모든 데몬, 쉘 프로세스, 커널 스레드, 인터럽트 처리기 및 분리된 CPU에서 디스패치할 수 있는 모든 작업을 실행하는 CPU입니다. 실시간 제한이 비활성화된 하우스키핑 CPU의 경우
stalld
는 기본 워크로드를 실행하는 CPU를 모니터링하고 Cryostat_FIFO
사용량 루프로 CPU를 할당하므로 이전에 정의된 허용 가능한 추가 노이즈에서 필요에 따라 stalled 스레드를 감지하고 스레드 우선 순위를 개선하는 데 도움이 됩니다. 실시간 제한 메커니즘으로 인해 기본 워크로드에서 복구할 수 없는 노이즈가 발생하는 경우stalld
가 선호될 수 있습니다.stalld
를 사용하면 starved 스레드를 강화하여 도입되는 노이즈를 보다 정확하게 제어할 수 있습니다.stalld
가 실행될 때 쉘 스크립트/usr/bin/throttlectl
은 실시간 제한을 자동으로 비활성화합니다./usr/bin/throttlectl show
스크립트를 사용하여 현재 제한 값을 나열할 수 있습니다.- 실시간 제한 비활성화
/proc
파일 시스템의 다음 매개변수는 실시간 제한을 제어합니다.-
/proc/sys/kernel/sched_rt_period_us
매개 변수는 마침표의 마이크로초 수를 지정하고 기본값은 1초입니다. -
/proc/sys/kernel/sched_rt_runtime_us
매개 변수는 제한되기 전에 실시간 작업에서 사용할 수 있는 마이크로초 단위 수를 지정하고 기본값은 사용 가능한 CPU 주기의 950,000 또는 95%입니다.echo
파일에 전달하여 제한을 비활성화할 수 있습니다.-1
> /proc/sys/kernel/sched_rt_runtime_us 명령을 사용하여 -1 값을sched_rt_runtime_us
-