RHEL for Real Time 이해


Red Hat Enterprise Linux for Real Time 10

RHEL for Real Time 커널의 기본 개념 및 사용 이해

Red Hat Customer Content Services

초록

짧은 대기 시간을 유지하고 대기 시간에 민감한 애플리케이션에서 일관된 응답 시간을 유지하기 위해 RHEL for Real Time 커널 튜닝에 대한 기본 개념 및 관련 참조를 이해하십시오.

Red Hat 문서에 관한 피드백 제공

문서 개선을 위한 의견에 감사드립니다. 어떻게 개선할 수 있는지 알려주십시오.

Jira를 통해 피드백 제출 (계정 필요)

  1. Jira 웹 사이트에 로그인합니다.
  2. 상단 탐색 바에서 생성을 클릭합니다.
  3. 요약 필드에 설명 제목을 입력합니다.
  4. 설명 필드에 개선을 위한 제안을 입력합니다. 문서의 관련 부분에 대한 링크를 포함합니다.
  5. 대화 상자 하단에서 생성 을 클릭합니다.

1장. RHEL for Real Time용 하드웨어 플랫폼

하드웨어는 시스템 작동 방식에 영향을 미치기 때문에 하드웨어를 올바르게 구성하는 것은 실시간 환경 설정에 중요한 역할을 합니다. 모든 하드웨어 플랫폼이 실시간이 가능한 것은 아니며 미세 조정이 가능합니다. 미세한 튜닝을 수행하기 전에 잠재적인 하드웨어 플랫폼을 실시간으로 사용할 수 있는지 확인해야 합니다.

하드웨어 플랫폼은 공급 업체에 따라 다릅니다. 하드웨어 대기 시간 탐지기(hwlatdetect) 프로그램을 사용하여 실시간 하드웨어 적합성을 테스트하고 확인할 수 있습니다. 이 프로그램은 대기 시간 탐지 커널 모듈을 제어하고 기본 하드웨어 또는 펌웨어 동작으로 인한 대기 시간을 감지하는 데 도움이 됩니다.

짧은 대기 시간 작업에 필요한 튜닝 단계가 완료되었습니다. 대기 시간이 짧은 문제를 줄이고 튜닝을 개선하는 방법은 벤더 설명서를 참조하십시오.

사전 요구 사항

  • RHEL-RT 패키지가 설치되어 있습니다.
  • 짧은 대기 시간 작업에 필요한 튜닝 단계가 완료됩니다. 시스템이SM(System Management Mode)으로 이동하도록 하는SMI(System Management Interrupts)를 줄이거나 제거하는 지침은 벤더 설명서를 참조하십시오.

    주의

    치명적인 하드웨어 오류가 발생할 수 있으므로SMI(System Management Interrupts)를 완전히 비활성화하지 않아야 합니다.

1.1. 프로세서 코어

실시간 프로세서 코어는 물리적 CPU(중앙 처리 장치)이며 시스템 코드를 실행합니다. 소켓은 컴퓨터의 프로세서와 마더보드 간 연결입니다. 소켓은 프로세서가 배치되는 마더보드의 위치입니다. 두 가지 프로세서 세트가 있습니다.

  • 하나의 소켓을 사용할 수 있는 코어를 사용하는 단일 코어 프로세서입니다.
  • 사용 가능한 코어가 4개인 Quad-core 프로세서는 하나의 소켓을 사용합니다.

실시간 환경을 설계할 때는 사용 가능한 코어 수, 코어 간 캐시 레이아웃, 코어가 물리적으로 연결된 방식을 알고 있어야 합니다.

여러 코어를 사용할 수 있는 경우 스레드 또는 프로세스를 사용합니다. 이러한 구성을 사용하지 않고 작성된 프로그램은 한 번에 단일 프로세서에서 실행됩니다. 멀티 코어 플랫폼은 다양한 유형의 운영에 서로 다른 코어를 사용할 때 이점을 제공합니다.

캐시

캐시는 전체 처리 시간 및 결정성에 큰 영향을 미칩니다. 종종 애플리케이션 스레드는 데이터 구조와 같은 공유 리소스에 대한 액세스를 동기화해야 합니다.

tuna CLI(명령줄 도구)를 사용하면 캐시 레이아웃을 결정하고 상호 작용 스레드를 코어에 바인딩하여 캐시를 공유할 수 있습니다. 캐시 공유는 상호 제외 기본(mutex, 조건 변수 또는 유사)와 데이터 구조가 동일한 캐시를 사용하도록 하여 메모리 오류를 줄입니다.

상호 연결

시스템의 코어 수를 늘리면 상호 연결에 대한 충돌하는 요구 사항이 발생할 수 있습니다. 이를 통해 실시간 시스템의 코어 간에 발생하는 충돌을 감지할 수 있도록 상호 연결 토폴로지를 결정해야 합니다.

많은 하드웨어 벤더들이 이제 NUMA(Non-Uniform Memory Access) 아키텍처로 알려진 코어와 메모리 간의 투명한 상호 연결 네트워크를 제공합니다.

NUMA는 멀티프로세싱에 사용되는 시스템 메모리 설계로, 메모리 액세스 시간은 프로세서와 관련된 메모리 위치에 따라 달라집니다. NUMA를 사용하면 프로세서는 다른 프로세서의 메모리 또는 프로세서 간에 공유되는 메모리와 같이 로컬이 아닌 메모리보다 더 빠르게 자체 로컬 메모리에 액세스할 수 있습니다. NUMA 시스템에서 상호 연결 토폴로지를 이해하면 인접한 코어에서 자주 통신하는 스레드를 배치할 수 있습니다.

tasksetnumactl 유틸리티는 CPU 토폴로지를 결정합니다. taskset 은 메모리 노드와 같은 NUMA 리소스 없이 CPU 선호도를 정의하고 numactl 은 프로세스 및 공유 메모리에 대한 NUMA 정책을 제어합니다.

2장. RHEL for Real Time의 메모리 관리

실시간 시스템은 사용자 공간 애플리케이션에서 참조하는 주소가 실제 주소로 변환되는 가상 메모리 시스템을 사용합니다. 변환은 기본 컴퓨팅 시스템에서 페이지 테이블 및 주소 변환 하드웨어의 조합을 통해 수행됩니다. 프로그램과 실제 메모리 사이에 변환 메커니즘을 갖는 장점은 운영 체제가 필요할 때 또는 CPU 요청 시 페이지를 스왑 할 수 있다는 것입니다.

실시간으로 스토리지에서 기본 메모리로 페이지를 스왑하기 위해 이전에 사용한 페이지 테이블 항목이 유효하지 않은 것으로 표시됩니다. 결과적으로 정상적인 메모리 부족 상태에서도 운영 체제는 한 애플리케이션에서 페이지를 검색하고 다른 애플리케이션에 제공할 수 있습니다. 이로 인해 예기치 않은 시스템 동작이 발생할 수 있습니다.

메모리 할당 구현에는 수요 페이징 메커니즘 및 메모리 잠금(mlock()) 시스템 호출이 포함됩니다.

참고

다른 캐시 및 NUMA 도메인에서 CPU에 대한 데이터 정보를 공유하면 트래픽 문제와 병목 현상이 발생할 수 있습니다.

다중 스레드 애플리케이션을 작성할 때 데이터 할당을 설계하기 전에 머신 토폴로지를 고려하십시오. 토폴로지는 메모리 계층 구조이며 CPU 캐시와 NUMA(Non-Uniform Memory Access) 노드를 포함합니다.

2.1. 요청 페이징

수요 페이징은 페이지 스와핑이 있는 페이징 시스템과 유사합니다. 시스템은 필요한 경우 또는 CPU 요구에 따라 보조 메모리에 저장된 페이지를 로드합니다. 프로그램에서 생성된 모든 메모리 주소는 프로세서의 주소 변환 메커니즘을 통과합니다. 그러면 주소가 프로세스별 가상 주소에서 실제 메모리 주소로 변환됩니다. 이를 가상 메모리라고 합니다. 변환 메커니즘의 두 가지 주요 구성 요소는 페이지 테이블 및 변환 조회 버퍼(TLB)입니다.

페이지 테이블

페이지 테이블은 가상 메모리와 실제 메모리에 대한 매핑을 포함하는 물리적 메모리의 다중 수준 테이블입니다. 이러한 매핑은 프로세서의 가상 메모리 변환 하드웨어에서 읽을 수 있습니다.

할당된 물리적 주소를 가진 페이지 테이블 항목을 상주 작업 세트라고 합니다. 운영 체제가 다른 프로세스의 메모리를 해제해야 하는 경우 상주 작업 집합에서 페이지를 스왑할 수 있습니다. 페이지를 스와핑할 때 해당 페이지 내의 가상 주소에 대한 참조로 페이지 폴트가 생성되고 페이지가 재할당됩니다.

시스템이 물리적 메모리에서 매우 낮으면 스왑 프로세스가 중단되기 시작하여 프로세스에서 페이지를 지속적으로 훔치고 프로세스를 완료할 수 없습니다. /proc/vmstat 파일에서 pgfault 값을 확인하여 가상 메모리 통계를 모니터링할 수 있습니다.

번역 조회 버퍼

TLB(Transformation Lookaside Buffers)는 가상 메모리 변환의 하드웨어 캐시입니다. TLB가 있는 프로세서 코어는 페이지 테이블 항목의 메모리 읽기를 시작하는 것과 함께 TLB를 병렬로 확인합니다. 가상 주소의 TLB 항목이 유효한 경우 메모리 읽기가 중단되고 TLB의 값이 주소 변환에 사용됩니다.

TLB는 참조의 지역성 원칙에 따라 작동합니다. 즉, 코드가 상당한 기간 동안 메모리의 한 영역에 남아 있으면 (예: 루프 또는 호출 관련 기능) TLB 참조는 주소 변환의 주요 메모리를 사용하지 않습니다. 이는 처리 시간을 크게 가속화할 수 있습니다.

결정적 및 빠른 코드를 작성할 때 참조의 현지성을 유지하는 함수를 사용합니다. 이는 재귀 대신 루프를 사용하는 것을 의미할 수 있습니다. 재귀를 피할 수 없는 경우 함수 끝에 재귀 호출을 배치합니다. 이를 tail-recursion이라고 하며, 이를 통해 비교적 작은 메모리 영역에서 코드가 작동하고 기본 메모리에서 테이블 번역을 호출하는 것을 방지할 수 있습니다.

2.2. 메이저 및 마이너 페이지 폴트

RHEL for Real Time은 물리적 메모리를 페이지라는 청크로 분할한 다음 가상 메모리에 매핑하여 메모리를 할당합니다. 프로세스에서 매핑되지 않았거나 더 이상 메모리에서 사용할 수 없는 특정 페이지가 필요한 경우 실시간으로 오류가 발생합니다. 따라서 오류는 기본적으로 CPU에 필요한 경우 페이지를 사용할 수 없음을 의미합니다. 프로세스가 페이지 폴트가 발생하면 커널이 이 오류를 처리할 때까지 모든 스레드가 중지됩니다. 이 문제를 해결하는 방법에는 여러 가지가 있지만 가장 좋은 해결책은 페이지 오류를 피하기 위해 소스 코드를 조정하는 것입니다.

사소한 페이지 폴트

프로세스가 초기화되기 전에 메모리 부분에 액세스하려고 할 때 사소한 페이지 폴트가 발생합니다. 이러한 시나리오에서 시스템은 메모리 맵 또는 기타 관리 구조를 채우기 위해 작업을 수행합니다. 사소한 페이지 폴트의 심각도는 시스템 로드 및 기타 요인에 따라 달라질 수 있지만 일반적으로 짧고 잘못된 영향을 미칠 수 있습니다.

주요 페이지 폴트

실시간 주요 오류는 시스템이 메모리 버퍼를 디스크와 동기화하거나, 다른 프로세스에 속하는 스왑 메모리 페이지 또는 다른 입력 출력(I/O) 활동을 수행하여 메모리를 해제해야 하는 경우 발생합니다. 이는 프로세서가 물리적 페이지가 할당되지 않은 가상 메모리 주소를 참조할 때 발생합니다. 빈 페이지에 대한 참조로 인해 프로세서가 오류를 실행하고 커널 코드가 페이지를 할당하도록 지시하여 대기 시간이 크게 증가합니다.

실시간으로 애플리케이션에 성능 저하가 표시되면 /proc/ 디렉토리에서 페이지 폴트와 관련된 프로세스 정보를 확인하는 것이 좋습니다. cat 명령을 사용하여 특정 PID(프로세스 ID)의 경우 다음과 같은 관련 항목에 대해 /proc/PID/stat 파일을 볼 수 있습니다.

  • 필드 2: 실행 가능한 파일 이름입니다.
  • 10 필드: 사소한 페이지 폴트 수입니다.
  • 12 필드: 주요 페이지 폴트 수.

다음 예제에서는 /proc/PID/stat 파일의 두 번째, 10번째 및 twelfth 행만 반환하는 cat 명령과 pipe 함수로 페이지 폴트를 보는 방법을 보여줍니다.

# cat /proc/3366/stat | cut -d\ -f2,10,12
  (bash) 5389 0

예제 출력에서 PID 3366이 있는 프로세스는 bash이며 5389 마이너 페이지 폴트와 주요 페이지 폴트가 없습니다.

2.3. mlock 시스템 호출

메모리 잠금(mlock()) 시스템 호출을 사용하면 프로세스를 호출하여 지정된 주소 공간 범위를 잠그거나 잠금 해제하여 Linux가 잠긴 메모리를 스왑 공간으로 페이징하지 못하도록 합니다. 페이지 테이블 항목에 실제 페이지를 할당한 후에는 해당 페이지에 대한 참조가 상대적으로 빠릅니다. 메모리 잠금 시스템 호출은 mlock()munlock() 카테고리로 분류됩니다.

mlock()munlock() 시스템은 잠금을 호출하고 지정된 프로세스 주소 페이지의 범위를 잠금 해제합니다. 성공하면 munlock() 시스템 호출이 페이지를 잠금 해제할 때까지 지정된 범위의 페이지가 메모리에 남아 있습니다.

mlock()munlock() 시스템 호출에는 다음과 같은 매개변수가 필요합니다.

  • addr: 주소 범위의 시작을 지정합니다.
  • Len: 주소 공간의 길이를 바이트 단위로 지정합니다.

성공하면 mlock()munlock() 시스템 호출은 0을 반환합니다. 오류가 발생하면 -1을 반환하고 오류를 나타내기 위해 errno 를 설정합니다.

mlockall()munlockall() 시스템 호출은 모든 프로그램 공간을 잠금 또는 잠금 해제합니다.

참고

mlock() 시스템 호출은 프로그램에 페이지 I/O가 없는지 확인하지 않습니다. 데이터가 메모리에 유지되지만 동일한 페이지에 유지되도록 보장할 수 없습니다. move_pages 및 메모리 컴팩트기와 같은 다른 함수는 mlock() 의 사용과 관계없이 데이터를 이동할 수 있습니다.

메모리 잠금은 페이지 기반으로 생성되며 스택되지 않습니다. 동적으로 할당된 두 개의 메모리 세그먼트가 mlock() 또는 mlockall() 에 의해 두 번 잠긴 동일한 페이지를 공유하는 경우 단일 munlock() 또는 munlockall() 시스템 호출을 사용하여 잠금을 해제합니다. 따라서 이중 잠금 또는 단일 잠금 해제 문제를 방지하기 위해 애플리케이션이 잠금 해제하는 페이지를 알고 있어야 합니다.

다음은 이중 잠금 또는 단일 잠금 문제를 완화하는 가장 일반적인 두 가지 해결 방법입니다.

  • 할당 및 잠긴 메모리 영역을 추적하고 페이지를 잠금 해제하기 전에 페이지 할당 수를 확인하는 래퍼 함수를 생성합니다. 장치 드라이버에서 사용되는 리소스 수 계산 원칙입니다.
  • 페이지에서 이중 잠금을 방지하기 위해 페이지 크기 및 정렬을 기반으로 메모리 할당을 만듭니다.

2.4. 공유 라이브러리

RHEL for Real Time 공유 라이브러리는 동적 공유 오브젝트(DSO)라고 하며 함수라는 미리 컴파일된 코드 블록 컬렉션입니다. 이러한 함수는 여러 프로그램에서 재사용할 수 있으며 런타임 시 로드되거나 컴파일됩니다.

Linux는 다음 두 가지 라이브러리 클래스를 지원합니다.

  • 동적 또는 공유 라이브러리: 실행 파일 외부에 별도의 파일로 존재합니다. 이러한 파일은 메모리에 로드되고 런타임 시 매핑됩니다.
  • 정적 라이브러리: 컴파일 시 프로그램에 정적으로 연결된 파일입니다.

ld.so 동적 링커는 프로그램에 필요한 공유 라이브러리를 로드한 다음 코드를 실행합니다. DSO 함수는 메모리의 라이브러리를 한 번 로드하고 여러 프로세스가 프로세스의 주소 공간에 매핑하여 개체를 참조할 수 있습니다. LD_BIND_NOW 변수를 사용하여 컴파일 시 로드되도록 동적 라이브러리를 구성할 수 있습니다.

프로그램 초기화 전에 기호를 평가하면 애플리케이션 런타임에 평가하면 메모리 페이지가 외부 디스크에 있는 경우 대기 시간이 발생할 수 있으므로 성능이 향상될 수 있습니다.

2.5. 공유 메모리

RHEL for Real Time에서 공유 메모리는 여러 프로세스 간에 공유되는 메모리 공간입니다. 프로그램 스레드를 사용하면 한 프로세스 컨텍스트에서 생성된 모든 스레드가 동일한 주소 공간을 공유할 수 있습니다. 이렇게 하면 스레드가 모든 데이터 구조에 액세스할 수 있습니다. POSIX 공유 메모리 호출을 사용하면 주소 공간의 일부를 공유하도록 프로세스를 구성할 수 있습니다.

다음과 같은 지원되는 POSIX 공유 메모리 호출을 사용할 수 있습니다.

  • shm_open(): 새 POSIX 공유 메모리 오브젝트를 생성하고 엽니다.
  • shm_unlink(): POSIX 공유 메모리 오브젝트를 연결 해제합니다.
  • mmap(): 호출 프로세스의 가상 주소 공간에 새 매핑을 생성합니다.
참고

System V IPC shmem() 호출 세트를 사용하여 두 프로세스 간에 메모리 영역을 공유하는 메커니즘은 더 이상 사용되지 않으며 RHEL for Real Time에서 더 이상 지원되지 않습니다.

Hidden -ng 툴은 치명적이지 않은 조건에서 효율성의 좋은 수준을 유지하기 위해 시스템의 기능을 측정합니다. stress-ng 툴은 모든 커널 인터페이스를 로드하고 강조하기 위해 워크로드 생성기입니다. 여기에는 학회로 알려진 다양한 학계 메커니즘이 포함됩니다. 부하 테스트는 머신 작업을 어렵게 만들고 시스템이 과도하게 작동할 때 발생하는 열 오버런 및 운영 체제 버그와 같은 하드웨어 문제를 트립합니다.

Cryostat 이상의 다양한 테스트가 있습니다. 여기에는 부동 소수점, 정수, 비트 조작, 제어 흐름 및 가상 메모리 테스트를 수행하는 CPU별 테스트가 포함됩니다.

참고

일부 테스트는 제대로 설계되지 않은 하드웨어에서 시스템의 열 영역 트립 지점에 영향을 미칠 수 있으므로 주의해서 가중한 툴을 사용하십시오. 이는 시스템 성능에 영향을 미칠 수 있으며 과도한 시스템 충돌로 인해 중지하기 어려울 수 있습니다.

3.1. CPU 부동 소수점 단위 및 프로세서 데이터 캐시 테스트

부동 소수점 단위는 부동 소수점 연산을 수행하는 프로세서의 기능 부분입니다.A floating point unit is the functional part of the processor that performs floating point arithmetic operations. 부동 소수점 단위는 수학적 작업을 처리하고 부동 숫자 또는 10진수 계산을 더 간단하게 만듭니다.

--matrix-method 옵션을 사용하면 CPU 부동 소수점 작업 및 프로세서 데이터 캐시 테스트를 과부하시킬 수 있습니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 60초 동안 하나의 CPU에서 부동 지점을 테스트하려면 --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

    CPU 번호가 0인 특수 모드에서 실행 가능한 CPU를 쿼리하여 CPU 번호를 지정할 필요가 없습니다.

    필요한 총 CPU 시간은 4x 60초(240초)이며, 0.13%가 커널에 있고, 85.50%는 사용자 시간이며, stress-ng 는 모든 CPU의 85.64%를 실행합니다.

  • POSIX 메시지 큐를 사용하여 프로세스 간에 전달되는 메시지를 테스트하려면 -mq 옵션을 사용합니다.

    # stress-ng --mq 0 -t 30s --times --perf

    mq 옵션은 POSIX 메시지 큐를 사용하여 컨텍스트 전환을 강제하도록 특정 수의 프로세스를 구성합니다. 이 부하 테스트는 낮은 데이터 캐시 누락을 목표로 합니다.

3.2. 여러 과부하 메커니즘을 사용하여 CPU 테스트

stress-ng 툴은 여러 번의 과부하 테스트를 실행합니다. 기본 모드에서는 지정된 과부하 메커니즘을 병렬로 실행합니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 다음과 같이 여러 CPU 스포저 인스턴스를 실행합니다.

    # stress-ng --cpu 2 --matrix 1 --mq 3 -t 5m

    이 예에서 stress-ng 는 CPU 스포터의 두 인스턴스, 매트릭스 과부하 인스턴스 중 하나 인스턴스와 5분 동안 테스트하기 위한 메시지 큐 과부하의 인스턴스 3개를 실행합니다.

  • 모든 stress 테스트를 병렬로 실행하려면 --all 옵션을 사용합니다.

    # stress-ng --all 2

    이 예에서 stress-ng 는 모든 과부하 테스트의 두 인스턴스를 병렬로 실행합니다.

  • 특정 순서로 각각의 다른 강조자를 실행하려면 --seq 옵션을 사용합니다.

    # stress-ng --seq 4 -t 20

    이 예에서 stress-ng 는 온라인 CPU 수와 일치하는 각 과부하의 인스턴스 수와 함께 20분 동안 하나씩 모든 과부하를 실행합니다.

  • 테스트 실행에서 특정 강조자를 제외하려면 -x 옵션을 사용합니다.

    # stress-ng --seq 1 -x numa,matrix,hdd

    이 예에서 stress-ngnuma,hddkey stressors 메커니즘을 제외하고 각 강조자를 실행합니다.

3.3. CPU heat 생성 측정

CPU heat 생성을 측정하기 위해 지정된 과부하는 최대 heat 생성에서 시스템의 난관 신뢰성 및 안정성을 테스트하기 위해 짧은 기간 동안 높은 온도를 생성합니다. --matrix-size 옵션을 사용하면 짧은 기간 동안 Celsius 수준의 CPU 온도를 측정할 수 있습니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  1. 지정된 기간 동안 높은 온도에서 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초 동안 elsius에 도달하도록 프로세서 패키지 열 영역을 구성합니다.

  2. 선택 사항: 실행 종료 시 보고서를 인쇄하려면 --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

3.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 작업을 표시합니다.

3.5. 가상 메모리 부족 생성

메모리 부족 상태에 있으면 커널이 스왑에 페이지 쓰기를 시작합니다. --page-in 옵션을 사용하여 non-resident 페이지가 가상 메모리로 다시 스왑되도록 하여 가상 메모리를 과부하시킬 수 있습니다. 이로 인해 가상 머신이 크게 수행됩니다. --page-in 옵션을 사용하면 bigheap,mmapvm(가상 시스템) 과부하에 이 모드를 활성화할 수 있습니다. --page-in 옵션은 코어가 아닌 할당된 페이지를 터치하여 페이지로 강제 적용합니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 가상 메모리 테스트를 강조하려면 --page-in 옵션을 사용합니다.

    # stress-ng --vm 2 --vm-bytes 2G --mmap 2 --mmap-bytes 2G --page-in

    이 예에서는 할당된 버퍼 크기보다 낮은 4GB 메모리, 2x 2GB의 vm stressor 및 --page-in 이 활성화된 2x 2GB의 mmap 스포터가 활성화된 시스템에서 메모리 부족을 테스트합니다.

3.6. 장치에서 대규모 인터럽트 로드 테스트

고주파에서 타이머를 실행하면 큰 인터럽트 로드를 생성할 수 있습니다. 적절하게 선택된 타이머 빈도를 가진 --timer 다운 로더는 초당 많은 인터럽트를 강제할 수 있습니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 인터럽트 로드를 생성하려면 --timer 옵션을 사용합니다.

    # stress-ng --timer 32 --timer-freq 1000000

    이 예에서 stress-ng 는 1#159에서 32개의 인스턴스를 테스트합니다.

3.7. 프로그램에서 주요 페이지 폴트 생성

stress-ng 를 사용하면 메모리에 로드되지 않은 페이지에 주요 페이지 폴트를 생성하여 페이지 폴트 속도를 테스트하고 분석할 수 있습니다. 새 커널 버전에서 userfaultfd 메커니즘은 프로세스의 가상 메모리 레이아웃에서 페이지 폴트에 대한 스레드를 찾는 오류를 알립니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 초기 커널 버전에서 주요 페이지 폴트를 생성하려면 다음을 사용합니다.

    # stress-ng --fault 0 --perf -t 1m
  • 새 커널 버전에서 주요 페이지 폴트를 생성하려면 다음을 사용합니다.

    # stress-ng --userfaultfd 0 --perf -t 1m

3.8. CPU 과부하 테스트 메커니즘 보기

CPU 스포크 테스트에는 CPU를 실행하는 방법이 포함되어 있습니다. 어떤 옵션을 사용하여 모든 메서드를 볼 수 있도록 출력을 출력할 수 있습니다.

기본적으로 테스트 방법을 지정하지 않으면 강조자가 라운드 로빈 방식으로 모든 강조자를 확인하여 각 스포터를 테스트합니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  1. 사용 가능한 모든 과부하 메커니즘을 출력하고 다음 옵션을 사용합니다.

    # 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
  2. --cpu-method 옵션을 사용하여 특정 CPU stress 방법을 지정합니다.

    # stress-ng --cpu 1 --cpu-method fft -t 1m

3.9. 확인 모드 사용

테스트가 활성화되면 확인 모드는 결과를 검증합니다. 이는 테스트 실행에서 메모리 콘텐츠를 확인하고 예기치 않은 오류를 보고합니다.

모든 과부하에는 확인 모드가 없으며 이를 활성화하면 이 모드에서 추가 검증 단계가 실행되기 때문에 bogo 작업 통계가 줄어듭니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있습니다.

프로세스

  • 과부하 테스트 결과를 검증하려면 --verify 옵션을 사용합니다.

    # stress-ng --vm 1 --vm-bytes 2G --verify -v

    이 예에서 stress-ng--verify 모드로 구성된 vm stressor를 사용하여 사실상 매핑된 메모리에 대한 전체 메모리 검사 출력을 출력합니다. 정상은 메모리에 대한 읽기 및 쓰기 결과를 확인합니다.

4장. RHEL for Real Time에서 하드웨어 중단

실시간 시스템은 주기적으로 유지 관리 및 시스템 스케줄링 결정을 수행하는 반-일반 "시너" 인터럽트를 포함하여 작업 과정을 통해 많은 인터럽트를 수신합니다. 또한 시스템은 NMI(Nonmaskable Interrupt) 및 SMI(System Management Interrupt)와 같은 특별한 종류의 인터럽트를 수신할 수 있습니다. 하드웨어 인터럽트는 장치에서 주의가 필요한 시스템의 물리적 상태 변경을 나타내는 데 사용됩니다. 예를 들어, 일련의 데이터 블록을 읽거나 네트워크 장치가 네트워크 패킷을 포함하는 버퍼를 처리한 경우 하드 디스크 신호입니다.

인터럽트가 실시간으로 발생하면 시스템은 활성 프로그램이 중지되고 인터럽트 처리기를 실행합니다.

실시간 하드웨어 인터럽트는 인터럽트 번호에 의해 참조됩니다. 이러한 숫자는 인터럽트를 생성한 하드웨어 조각으로 다시 매핑됩니다. 이를 통해 시스템은 인터럽트를 생성한 장치와 발생한 시간을 모니터링할 수 있습니다. 인터럽트가 실시간으로 발생하면 시스템은 활성 프로그램을 중지하고 인터럽트 처리기를 실행합니다. 처리기는 실행 중인 다른 프로그램 및 시스템 활동을 선점합니다. 이로 인해 전체 시스템이 느려지고 대기 시간이 발생할 수 있습니다.

RHEL for Real Time은 인터럽트 처리 방식을 수정하여 성능을 개선하고 대기 시간을 줄입니다. cat /proc/interrupts 명령을 사용하면 출력을 출력하여 발생한 하드웨어 인터럽트 유형, 수신된 인터럽트 수, 인터럽트의 대상 CPU, 인터럽트를 생성하는 장치를 볼 수 있습니다.

4.1. level-signaled 인터럽트

실시간으로 레벨 사인 인터럽트는 마운드 전환을 제공하는 전용 인터럽트 라인을 사용합니다. 장치 컨트롤러는 인터럽트 요청 라인에서 신호를 어설션하여 인터럽트를 발생시킵니다. 인터럽트 라인은 두 개의 출력 중 하나를 전송하여 바이너리 1 또는 바이너리 0을 나타냅니다.

행에 의해 인터럽트 신호가 전송되면 CPU가 재설정될 때까지 해당 상태로 유지됩니다. CPU는 상태 저장을 수행하고 인터럽트를 캡처하고 인터럽트 처리기를 디스패치합니다. 인터럽트 처리기는 인터럽트의 원인을 결정하고 필요한 서비스를 수행하여 인터럽트를 지우고 장치의 상태를 복원합니다. 레벨 서명 인터럽트는 더 안정적이고 여러 장치를 지원하지만 구현하기가 어렵습니다.

4.2. 메시지 서명 인터럽트

실시간에서 많은 시스템은 MSI(Message-signaled interrupts)를 사용하여 패킷 또는 메시지 기반 기전 버스에서 신호를 전용 메시지로 전송합니다. 이러한 유형의 버스의 일반적인 예는 PCI Express 또는 PCIe(Peripheral Component Interconnect Express)입니다. 이러한 장치는 PCIe 호스트 컨트롤러가 인터럽트 메시지로 해석되는 메시지 유형을 전송합니다. 그러면 호스트 컨트롤러가 의 메시지를 CPU로 보냅니다.

실시간으로, 하드웨어에 따라 PCIe 시스템은 다음 중 하나를 수행합니다.

  • PCIe 호스트 컨트롤러와 CPU 간의 전용 인터럽트 행을 사용하여 신호를 보냅니다.
  • CPU HyperTransport 버스를 통해 메시지를 보냅니다.

실시간으로 PCIe 시스템은 레거시 모드에서도 작동할 수 있습니다. 여기서 레거시 인터럽트 라인은 커널 명령줄에서 pci=nomsi 옵션을 사용하여 이전 운영 체제를 지원하거나 부팅 Linux 커널에서 구현됩니다.

4.3. 마스킹할 수 없는 인터럽트

실시간으로 마스킹할 수 없는 인터럽트는 시스템의 표준 인터럽트 마스킹 기술을 무시할 수 없는 하드웨어 인터럽트입니다. NMI는 마스크 가능한 인터럽트보다 우선 순위가 높습니다. NMI는 복구할 수 없는 하드웨어 오류에 대한 주의를 알리기 위해 발생합니다.

실시간 NMI는 일부 시스템에서 하드웨어 모니터로도 사용됩니다. 프로세서는 NMI를 수신할 때 인터럽트 벡터가 가리키는 NMI 처리기를 호출하여 NMI를 즉시 처리합니다. 지정된 시간 후에 트리거되지 않는 인터럽트와 같이 특정 조건이 충족되면 NMI 처리기에서 경고를 표시하고 문제에 대한 디버깅 정보를 제공합니다. 이를 통해 시스템 잠금을 식별하고 방지하는 데 도움이 됩니다.

실시간으로 마스크 가능한 인터럽트는 인터럽트 마스크 레지스터의 비트 마스크에 비트를 설정하여 무시할 수 있는 하드웨어 인터럽트입니다. CPU는 중요한 처리 중에 마스크 가능한 인터럽트를 일시적으로 무시할 수 있습니다.

4.4. 시스템 관리 인터럽트

실시간으로 시스템 관리 인터럽트(SMI)는 레거시 하드웨어 장치 에뮬레이션과 같은 확장된 기능을 제공하며 시스템 관리 작업에도 사용할 수 있습니다. SMIS는 마스크 불가능한 인터럽트 (NMI)와 유사하며 일반적으로 마스크를 사용할 수 없습니다. SMI가 발생하면 CPU가 시스템 관리 모드(SMM)로 들어갑니다. 이 모드에서 특수 하위 수준 처리기는 SMI를 처리하기 위해 실행됩니다. SMM은 일반적으로 시스템 관리 펌웨어, 종종 BIOS 또는 EFI에서 직접 제공됩니다.

실시간 SMI는 레거시 하드웨어 에뮬레이션을 제공하는 데 가장 자주 사용됩니다. 일반적인 예는 디스크lets 드라이브를 모방하는 것입니다. 디스크lets 드라이브가 연결되어 있지 않으면 운영 체제는 디스크 스탠자에 액세스하려고 시도하며 SMI를 트리거합니다. 이 시나리오에서 처리기는 운영 체제에 에뮬레이션된 장치를 대신 제공합니다. 그런 다음 운영 체제는 에뮬레이션을 레거시 장치로 처리합니다.

SMI는 실시간으로 운영 체제의 직접적인 개입 없이 시스템에 부정적인 영향을 미칠 수 있습니다. 잘못 작성된 SMI 처리 루틴은 수 밀리초의 CPU 시간을 사용할 수 있으며 운영 체제는 처리기를 선점하지 못할 수 있습니다. 이로 인해 다른 잘 조정되고 반응성이 높은 시스템에서 주기적인 높은 대기 시간을 생성할 수 있습니다. 벤더는 CPU 온도 및 팬 제어를 관리하기 위해 SMI 처리기를 사용할 수 있으므로 비활성화할 수 없습니다. 이러한 상황에서는 이러한 인터럽트를 사용할 때 발생하는 문제에 대해 공급업체에게 알려야 합니다.

실시간으로 hwlatdetect 유틸리티를 사용하여 SMI를 분리할 수 있습니다. rt-tests 패키지에서 사용할 수 있습니다. 이 유틸리티는 SMI 처리 루틴에서 CPU를 사용하는 기간을 측정합니다.

4.5. 고급 프로그래밍 가능 인터럽트 컨트롤러

Intel Corporation에서 개발한 고급 프로그래밍 가능 인터럽트 컨트롤러(APIC)는 다음을 수행할 수 있는 기능을 제공합니다.

  • 대량의 인터럽트를 처리하여 각각 특정 CPU 세트로 라우팅합니다.
  • CPU 간 통신을 지원하고 여러 장치가 단일 인터럽트 라인을 공유할 필요가 없습니다.

실시간 APIC는 확장 가능하고 관리 가능한 방식으로 다수의 하드웨어 인터럽트를 생성, 라우팅 및 처리하기 위해 함께 작동하는 일련의 장치 및 기술을 나타냅니다. 각 시스템 CPU에 내장된 로컬 APIC와 하드웨어 장치에 직접 연결된 여러 입력/출력 APIC를 사용합니다.

실시간으로 하드웨어 장치가 인터럽트를 생성할 때 연결된 I/O APIC는 시스템 APIC 버스 전체의 인터럽트를 특정 CPU로 탐지하고 라우팅합니다. 운영 체제는 IO-APIC가 장치에 연결되고 해당 장치 내의 인터럽트 라인을 알고 있습니다. Advanced Configuration and Power Interface Differentiated System Description Table (ACPI DSDT)에는 호스트 시스템 마더보드 및 주변 구성 요소의 특정 설정에 대한 정보가 포함되어 있으며 장치는 사용 가능한 인터럽트 소스에 대한 정보를 제공합니다. 이러한 두 가지 데이터 세트는 전체 인터럽트 계층 구조에 대한 정보를 제공합니다.

RHEL for Real Time은 계층 구조로 연결된 시스템 APIC 기반 인터럽트 관리 전략을 지원하고 특정 CPU 또는 CPU 세트를 대상으로 하는 대신 부하 분산 방식으로 CPU에 인터럽트를 전달합니다.

5장. 실시간 프로세스 및 스레드를 위한 RHEL

운영 체제의 RHEL for Real Time 주요 요소는 인터럽트 대기 시간과 스레드 전환 대기 시간을 최소화합니다. 모든 프로그램은 스레드와 프로세스를 사용하지만 RHEL for Real Time은 표준 Red Hat Enterprise Linux와는 다른 방식으로 처리합니다.

실시간으로 병렬 처리를 사용하면 작업 실행 및 대기 시간에서 효율성을 높일 수 있습니다. 병렬 처리는 CPU의 멀티 코어 인프라를 사용하여 여러 작업 또는 여러 하위 작업을 동시에 실행하는 경우입니다.

5.1. 프로세스

가장 간단한 관점에서 실시간 프로세스는 실행 중인 프로그램입니다. 용어 프로세스는 여러 스레드가 잠재적으로 포함된 독립적인 주소 공간을 나타냅니다. 한 주소 공간 내에서 실행되는 두 개 이상의 프로세스의 개념이 개발되면 Linux는 다른 프로세스와 주소 공간을 공유하는 프로세스 구조로 전환되었습니다. 이는 프로세스 데이터 구조가 작을 때 제대로 작동합니다.

UNIX® 스타일 프로세스 구성에는 다음이 포함됩니다.

  • 가상 메모리의 주소 매핑입니다.
  • 실행 컨텍스트(PC, 스택, 레지스터)입니다.
  • 주 및 회계 정보

실시간으로 각 프로세스는 종종 부모 스레드라고 하는 단일 스레드로 시작합니다. fork() 시스템 호출을 사용하여 상위 스레드에서 추가 스레드를 생성할 수 있습니다. fork() 는 새 프로세스 ID를 제외하고 상위 프로세스와 동일한 새 하위 프로세스를 생성합니다. 하위 프로세스는 생성 프로세스와 독립적으로 실행됩니다. 상위 및 하위 프로세스를 동시에 실행할 수 있습니다. fork()exec() 시스템 호출의 차이점은 fork() 가 상위 프로세스의 복사본인 새 프로세스를 시작하고 exec() 는 현재 프로세스 이미지를 새 프로세스 이미지로 대체한다는 것입니다.

실시간으로 fork() 시스템 호출이 성공하면 하위 프로세스의 프로세스 식별자가 반환되고 상위 프로세스는 0이 아닌 값을 반환합니다. 오류 발생 시 오류 번호를 반환합니다.

5.2. 스레드

실시간으로 여러 스레드가 프로세스 내에 존재할 수 있습니다. 프로세스의 모든 스레드는 가상 주소 공간과 시스템 리소스를 공유합니다. 스레드는 다음을 포함하는 스케줄링 가능한 엔티티입니다.

  • 프로그램 카운터(PC)입니다.
  • 레지스터 컨텍스트.
  • 스택 포인터입니다.

실시간에서는 병렬 처리를 생성하기 위한 잠재적인 메커니즘이 있습니다.

  • fork()exec() 함수 호출을 사용하여 새 프로세스를 생성합니다. fork() 호출은 호출되고 고유한 프로세스 식별자가 있는 프로세스의 정확한 중복을 생성합니다.
  • Posix 스레드(pthreads) API를 사용하여 이미 실행 중인 프로세스 내에서 새 스레드를 생성합니다.

실시간 스레드를 생성하기 전에 구성 요소 상호 작용 수준을 평가해야 합니다. 새 주소 공간을 만들고 새 프로세스로 실행하면 구성 요소가 서로 독립적이거나 상호 작용이 적을 때 유용합니다. 데이터를 공유하거나 자주 통신하는 데 구성 요소가 필요한 경우 하나의 주소 공간 내에서 스레드를 실행하는 것이 더 효율적입니다.

실시간으로 fork() 시스템 호출이 성공하면 0 값을 반환합니다. 오류 발생 시 오류 번호를 반환합니다.

6장. 실시간 RHEL에서 애플리케이션 타임스탬프 지정

빈번한 타임 스탬프를 수행하는 애플리케이션은 시계를 읽는 CPU 비용의 영향을 받습니다. 클럭을 읽는 데 사용되는 높은 비용과 시간은 애플리케이션의 성능에 부정적인 영향을 미칠 수 있습니다.

기본 클록보다 읽기 메커니즘이 있는 하드웨어 시계를 선택하여 시계를 읽는 비용을 줄일 수 있습니다.

RHEL for Real Time에서는 clock_gettime() 함수와 POSIX 클록을 사용하여 가능한 CPU 비용이 가장 낮은 클럭 읽기를 생성하여 추가 성능 이점을 얻을 수 있습니다.

이러한 이점은 높은 읽기 비용으로 하드웨어 클록을 사용하는 시스템에 대해 더 명확합니다.

6.1. 하드웨어 클럭

NUMA(Non-Uniform Memory Access) 및 SMP(Symmetric Multiprocessing)와 같은 다중 프로세서 시스템에서 발견된 클럭 소스의 여러 인스턴스는 CPU 빈도 스케일링 또는 에너지 경제 모드 입력과 같은 시스템 이벤트에 반응하는 방식을 상호 작용하며 실시간 커널에 적합한 클럭 소스인지 결정합니다.

기본 클록 소스는 TSC(Time Stamp Cryostat)입니다. TSC를 사용할 수 없는 경우 HPET(High Precision Event Timer)이 두 번째 최상의 옵션입니다. 그러나 모든 시스템에 HPET 시계가 있는 것은 아니며 일부 HPET 클록은 신뢰할 수 없습니다.

TSC 및 HPET가 없는 다른 옵션에는 ACPI_PM (ACPI_PM), Programmable Interval Timer (PIT) 및 Real Time Clock (RTC)이 포함됩니다. 마지막 두 옵션은 읽기에는 비용이 많이 들거나 낮은 해상도(시간 단위)가 있으므로 실시간 커널과 함께 사용할 수 있습니다.

6.2. POSIX 클록

POSIX는 시간 소스를 구현하고 나타내는 표준입니다. 시스템의 다른 애플리케이션에 영향을 주지 않고 애플리케이션에 POSIX 시계를 할당할 수 있습니다. 이는 커널에서 선택하고 시스템 전체에서 구현되는 하드웨어 클록과 대조적입니다.

지정된 POSIX 시계를 읽는 데 사용되는 함수는 <time .h>에 정의된 clock_gettime() 입니다. clock_gettime() 과 반대되는 커널은 시스템 호출입니다. 사용자 프로세스가 clock_gettime() 을 호출할 때:

  1. 해당 C 라이브러리(glibc)는 sys_clock_gettime() 시스템 호출을 호출합니다.
  2. sys_clock_gettime() 은 요청된 작업을 수행합니다.
  3. sys_clock_gettime() 은 사용자 프로그램에 결과를 반환합니다.

그러나 사용자 애플리케이션에서 커널로의 컨텍스트 전환에는 CPU 비용이 있습니다. 이러한 비용은 매우 낮지만 작업이 수천 번 반복되면 누적된 비용이 애플리케이션의 전체 성능에 영향을 미칠 수 있습니다. 커널로 컨텍스트 전환을 방지하기 위해 더 빠르게 클럭을 읽을 수 있도록 CLOCK_MONOTONIC_COARSECLOCK_REALTIME_COARSE POSIX 클록에 대한 지원이 VDSO(가상 동적 공유 오브젝트) 라이브러리 함수 형태로 추가되었습니다.

_COARSE 클럭 변형 중 하나를 사용하여 clock_gettime() 에 의해 수행되는 시간 읽기는 커널 개입이 필요하지 않으며 사용자 공간에서 완전히 실행됩니다. 이는 상당한 성능 이점을 제공합니다. _COARSE 클록에 대한 시간 읽기에는 밀리 초(ms) 해상도가 있으므로 1ms보다 작은 시간 간격은 기록되지 않습니다. POSIX 클록의 _COARSE 변형은 밀리 초 클록 해상도를 수용할 수 있는 모든 애플리케이션에 적합합니다.

6.3. clock_gettime() function

다음 코드는 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

7장. 실시간 RHEL 스케줄링 정책

스케줄러는 실행할 실행 가능한 스레드를 결정하는 커널 구성 요소입니다. 각 스레드에는 sched_priority 라는 연결된 스케줄링 정책 및 정적 예약 우선순위가 있습니다. 예약은 선점되므로 현재 실행 중인 스레드가 더 높은 정적 우선 순위가 있는 스레드가 실행될 준비가 되면 중지됩니다. 그런 다음 실행 중인 스레드는 정적 우선 순위에 대한 대기 목록으로 돌아갑니다.

모든 Linux 스레드에는 다음 스케줄링 정책 중 하나가 있습니다.

  • Cryostat_OTHER 또는 Cryostat_NORMAL: 기본 정책입니다.
  • Cryostat_BATCH: Cryo stat_OTHER 와 유사하지만 방향은 점진적입니다.
  • Cryostat_IDLE: is the policy with lower priority than Cryo stat_OTHER.
  • Cryostat_FIFO: 첫 번째 실시간 정책입니다.
  • Cryostat_RR: 라운드 로빈 실시간 정책입니다.
  • Cryostat_DEADLINE: 작업 기한에 따라 작업의 우선 순위를 지정하는 스케줄러 정책입니다. 가장 빠른 절대 기한을 가진 작업이 먼저 실행됩니다.

7.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_FIFOCryostat_RR 스레드는 다음 이벤트 중 하나가 발생할 때까지 실행됩니다.

    • 스레드가 잠기거나 이벤트를 기다립니다.
    • 우선순위가 높은 실시간 스레드를 실행할 준비가 되었습니다.

      위의 이벤트 중 하나가 발생하지 않는 한 스레드는 지정된 프로세서에서 무기한 실행되지만 우선순위가 낮은 스레드는 실행 대기 중인 큐에 남아 있습니다. 이로 인해 시스템 서비스 스레드가 상주하고 스왑 아웃되지 않고 파일 시스템 데이터 플러시에 실패할 수 있습니다.

  • Cryostat_DEADLINE 정책

    Cryo stat_DEADLINE 정책은 타이밍 요구 사항을 지정합니다. 작업의 데드라인에 따라 각 작업을 예약합니다. 먼저 데드라인(EDF) 일정이 가장 빠른 작업이 먼저 실행됩니다.

    커널을 사용하려면 runtime Cryostatdeadline Cryostatperiod 가 true여야 합니다. 필수 옵션 간의 관계는 runtime Cryostatdeadline Cryostatperiod 입니다.

7.2. Cryostat_DEADLINE 정책에 대한 매개변수

Cryostat_DEADLINE 작업은 마침표,런타임데드라인 매개 변수로 지정됩니다. 이러한 매개변수의 값은 나노초의 정수입니다.

Expand
표 7.1. Cryostat_DEADLINE 매개변수
매개변수설명

기간

기간은 실시간 작업의 활성화 패턴입니다.

예를 들어, 비디오 처리 작업에 처리할 초당 60 프레임이 있는 경우 16밀리초마다 서비스에 대해 새 프레임이 큐에 추가됩니다. 따라서 기간은 16밀리초입니다.

runtime

runtime 은 출력을 생성하기 위해 작업에 할당된 CPU 실행 시간입니다. 실시간으로 최대 실행 시간(WCET)은 런타임 입니다.

예를 들어 비디오 처리 도구가 이미지를 처리하는 데 5밀리초인 잘못된 경우 5밀리초를 사용할 수 있는 경우 런타임 은 5밀리초입니다.

데드라인

데드라인 은 출력을 생성하는 최대 시간입니다.

예를 들어 작업이 10밀리초 내에 처리된 프레임을 제공해야 하는 경우 데드라인 은 10밀리초입니다.

7.3. Cryostat_DEADLINE 매개변수 구성

Red Hat Enterprise Linux의 sched_deadline_period_max_ussched_deadline_period_min_us 매개변수는 Cryostat_DEADLINE 스케줄링 정책의 커널 조정 가능한 매개변수입니다. 이러한 매개변수는 이 실시간 스케줄링 클래스를 사용하여 작업에 대해 허용되는 최대 및 최소 기간(마이크로초)을 제어합니다.

sched_deadline_period_max_ussched_deadline_period_min_us 는 함께 작동하여 period 값에 대한 허용 가능한 범위를 정의합니다.

  • min_us 는 과도한 리소스를 사용할 수 있는 빈도가 높은 작업을 방지합니다.
  • max_us 는 다른 작업의 성능이 저하될 수 있는 매우 긴 기간 작업을 방지합니다.
참고

매개 변수의 기본 구성을 사용합니다. 매개변수 값을 변경해야 하는 경우 실시간 환경에서 사용자 지정 값을 구성해야 합니다.

매개 변수의 값은 마이크로초 단위입니다. 예를 들어 1초는 100000 마이크로초와 동일합니다.

사전 요구 사항

  • 시스템에 대한 root 권한이 있어야 합니다.

프로세스

  1. sysctl 명령 중 하나를 사용하여 필요한 값을 일시적으로 설정합니다.

    • sched_deadline_period_max_us 매개변수를 사용하려면 다음 명령을 실행합니다.

      # sysctl -w kernel.sched_deadline_period_max_us=2000000
    • sched_deadline_period_min_us 매개변수를 사용하려면 다음 명령을 실행합니다.

      # sysctl -w kernel.sched_deadline_period_min_us=100
  2. 값을 영구적으로 설정합니다.

    • max_us 의 경우 /etc/sysctl.conf 를 편집하고 다음 행을 추가합니다.

      kernel.sched_deadline_period_max_us = 2000000
    • min_us 의 경우 /etc/sysctl.conf 를 편집하고 다음 행을 추가합니다.

      kernel.sched_deadline_period_min_us = 100
  3. 변경 사항을 적용합니다.

    # sysctl -p

검증

  • max_us 의 사용자 지정 값을 확인합니다.

    $ cat /proc/sys/kernel/sched_deadline_period_max_us
    2000000
  • min_us 의 사용자 지정 값을 확인합니다.

    $ cat /proc/sys/kernel/sched_deadline_period_min_us
    100

8장. 실시간 커널의 런타임 확인

런타임 확인은 시스템 이벤트와 공식 사양 간의 동작 동일성을 확인하는 가볍고 엄격한 방법입니다. 런타임 확인에는 추적 지점에 연결하는 커널에 통합된 모니터가 있습니다. 시스템 상태가 정의된 사양에서 벗어나는 경우 런타임 확인 프로그램은 반응기를 활성화하여 로그 파일에서 이벤트를 캡처하거나 시스템 종료와 같은 응답을 활성화하여 극단적인 경우 오류 전파를 방지합니다.

8.1. 런타임 모니터 및 반응기

RV(런타임 확인) 모니터는 RV 모니터 내에 캡슐화되고 정의된 사양과 커널 추적 간에 조정되어 추적 파일에서 런타임 이벤트를 캡처합니다. RV 모니터에는 다음이 포함됩니다.

  • 참조 모델은 시스템의 참조 모델입니다.
  • 모니터 인스턴스는 CPU당 모니터 또는 작업별 모니터와 같은 모니터의 인스턴스 집합입니다.
  • 모니터를 시스템에 연결하는 도우미 기능입니다.

런타임 시 시스템을 확인하고 모니터링하는 것 외에도 예기치 않은 시스템 이벤트에 대한 응답을 활성화할 수 있습니다. 반응 방식은 안전 크리티컬 시스템에서 시스템 실패를 방지하기 위해 종료와 같은 극단적인 반응을 시작하기 위해 추적 파일에서 이벤트를 캡처하는 것과는 다를 수 있습니다.

반응기는 필요에 따라 시스템 이벤트에 대한 응답을 정의하기 위해 RV 모니터에 사용할 수 있는 반응 방법입니다. 기본적으로 모니터는 작업의 추적 출력을 제공합니다.

8.2. 온라인 런타임 모니터

RV(런타임 확인) 모니터는 다음과 같은 유형으로 분류됩니다.

  • 온라인 모니터는 시스템이 실행되는 동안 추적에서 이벤트를 캡처합니다.

    온라인 모니터는 이벤트 처리가 시스템 실행에 연결된 경우 동기적으로 수행됩니다. 이렇게 하면 이벤트 모니터링 중에 시스템이 차단됩니다. 온라인 모니터는 시스템에서 실행이 분리되고 다른 컴퓨터에서 실행되는 경우 비동기식입니다. 그러나 저장된 실행 로그 파일이 필요합니다.

  • 오프라인에서는 이벤트가 발생한 후 생성된 프로세스 추적을 모니터링합니다.

    오프라인 런타임 확인에서는 일반적으로 영구 저장소에서 저장된 추적 로그 파일을 읽고 정보를 캡처합니다. 오프라인 모니터는 파일에 저장된 이벤트가 있는 경우에만 작동할 수 있습니다.

8.3. 사용자 인터페이스

사용자 인터페이스는 /sys/kernel/tracing/rv 에 있으며 추적 인터페이스와 유사합니다. 사용자 인터페이스에는 언급된 파일 및 폴더가 포함됩니다.

Expand
설정설명명령 예

available_monitors

한 줄에 하나씩 사용 가능한 모니터를 표시합니다.

# cat available_monitors

available_reactors

한 줄에 하나씩 사용 가능한 반응기를 표시합니다.

# cat available_reactors

enabled_monitors

한 줄에 하나씩 활성화된 모니터를 표시합니다. 두 개 이상의 모니터를 동시에 활성화할 수 있습니다.

'!' 접두사를 사용하여 모니터 이름을 작성하면 모니터가 비활성화되고 파일을 자르면 활성화된 모든 모니터가 비활성화됩니다.

# cat enabled_monitors

# Echo wip > enabled_monitors

# Echo '!wip'>> enabled_monitors

모니터/

모니터/ 디렉터리는 tracefs 파일 시스템의 events 디렉토리와 유사하며 각 모니터는 monitors/ 내에 자체 디렉터리가 있습니다.

# CD Monitor/wip/

모니터/MONITOR/reactors

"[]" 내의 특정 MONITOR에 대한 선택 반응과 함께 사용 가능한 반응기를 나열합니다. 기본값은 no operation (nop) reactor입니다.

반응자 이름을 작성하면 특정 MONITOR에 통합됩니다.

# cat monitors/wip/reactors

monitoring_on

추적 인터페이스에서 tracing_ontracing_off 전환기를 시작합니다.

0 을 작성하면 모니터링이 중지되고 1 은 모니터링을 계속합니다. 전환기에서는 활성화된 모니터를 비활성화하지 않지만 이벤트를 모니터링하지 못하도록 관련 모니터를 중지합니다.

 

reacting_on

reactors를 활성화합니다. 0 을 작성하면 응답이 비활성화되고 1 은 응답을 활성화합니다.

 

모니터/MONITOR/desc

모니터 설명 표시

 

모니터/MONITOR/enable

모니터의 현재 상태를 표시합니다. 0 을 작성하면 모니터가 비활성화되고 1 은 모니터를 활성화합니다.

 

9장. RHEL for Real Time의 유사성

실시간으로 시스템의 모든 스레드 및 인터럽트 소스에는 프로세서 선호도 속성이 있습니다. 운영 체제 스케줄러는 이 정보를 사용하여 어떤 CPU에서 실행할 스레드 및 인터럽트를 결정합니다.

실시간으로 유사성은 비트 마스크로 표시됩니다. 여기서 마스크의 각 비트는 CPU 코어를 나타냅니다. 비트가 1로 설정되면 스레드 또는 인터럽트가 해당 코어에서 실행될 수 있습니다. 0인 경우 스레드 또는 인터럽트는 코어에서 실행되지 않습니다. 선호도 비트 마스크의 기본값은 모두이므로 스레드 또는 인터럽트는 시스템의 모든 코어에서 실행될 수 있습니다.

기본적으로 프로세스는 모든 CPU에서 실행할 수 있습니다. 그러나 프로세스의 선호도를 변경하여 사전 정의된 CPU에서 프로세스를 실행하도록 프로세스에 지시할 수 있습니다. 하위 프로세스는 상위 프로세스의 CPU 특성을 상속합니다.

보다 일반적인 선호도 설정 중 일부는 다음과 같습니다.

  • 모든 시스템 프로세스에 대해 하나의 CPU 코어를 예약하고 나머지 코어에서 애플리케이션을 실행할 수 있습니다.
  • 동일한 CPU에서 스레드 애플리케이션 및 지정된 커널 스레드(예: 네트워크 softirq 또는 드라이버 스레드)를 허용합니다.
  • 각 CPU의 쌍 생산자 및 소비자 스레드.
참고

선호도 설정은 좋은 예상 동작을 위해 프로그램과 함께 설계되어야 합니다.

9.1. 프로세서 유사성

기본적으로 프로세스는 모든 CPU에서 실행할 수 있습니다. 그러나 프로세스의 선호도를 변경하여 사전 정의된 CPU에서 실행되도록 프로세스를 구성할 수 있습니다. 하위 프로세스는 상위 프로세스의 CPU 특성을 상속합니다.

시스템에서 기능 조정에 대한 실시간 관행은 애플리케이션을 실행하는 데 필요한 코어 수를 확인한 다음 해당 코어를 격리하는 것입니다. 이는 Tuna 툴을 사용하거나 쉘 스크립트를 사용하여 비트마스크 값을 수정할 수 있습니다.

taskset 명령은 프로세스의 선호도를 변경하고 /proc/ filesystem 항목을 수정하면 인터럽트의 선호도를 변경할 수 있습니다. p 또는 --pid 옵션과 함께 taskset 명령을 사용하고 프로세스의 PID(프로세스 ID)를 사용하여 프로세스의 선호도를 확인합니다.

-c 또는 --cpu-list 옵션은 비트마스크 대신 코어 수 목록을 표시합니다. 특정 프로세스를 바인딩할 CPU 수를 지정하여 선호도를 설정할 수 있습니다. 예를 들어 CPU 0 또는 CPU 1을 이전에 사용한 프로세스의 경우 CPU 1에서만 실행할 수 있도록 선호도를 변경할 수 있습니다. taskset 명령 외에도 sched_setaffinity() 시스템 호출을 사용하여 프로세서 선호도를 설정할 수도 있습니다.

9.2. Cryostat_DEADLINE 및 cpusets

커널의 데드라인 스케줄링 클래스( Cryostat_DEADLINE)는 제한된 기한이 지정된 작업에 대해 초기 데드라인(EDF)을 구현합니다. 작업 데드라인에 따라 작업의 우선 순위를 지정합니다. 가장 빠른 절대 데드라인이 먼저 수행됩니다. EDF 스케줄러 외에도 데드라인 스케줄러는 일정 대역폭 서버(CBS)도 구현합니다. CBS 알고리즘은 리소스 예약 프로토콜입니다.

CBS는 각 작업이 모든 기간 (T) 에서 실행 시간 (Q) 을 수신하는 것을 보장합니다. 작업의 모든 활성화가 시작될 때 CBS는 작업의 실행 시간을 보완합니다. 작업이 실행되면 해당 런타임 을 사용하고 작업이 런타임 이 부족하면 작업이 제한되고 예약 해제됩니다. 제한 메커니즘은 단일 작업이 런타임 이상의 실행을 방지하고 다른 작업의 성능 문제를 방지하는 데 도움이 됩니다.

실시간으로 데드라인 작업으로 시스템 과부하를 방지하기 위해 데드라인 스케줄러는 데드라인 스케줄러로 실행되도록 작업이 구성될 때마다 실행되는 승인 테스트를 구현합니다. 수락 테스트에서는 Cryostat _DEADLINE 작업이 kernel.sched_rt_runtime_us/kernel.sched_rt_period_us 파일에 지정된 CPU 시간보다 더 많은 CPU 시간을 사용하지 않도록 합니다. 기본적으로 1s를 통한 950ms입니다.

10장. RHEL for Real Time의 스레드 동기화 메커니즘

실시간으로 두 개 이상의 스레드가 공유 리소스에 동시에 액세스해야 하는 경우 스레드는 스레드 동기화 메커니즘을 사용하여 조정합니다. 스레드 동기화를 사용하면 한 번에 하나의 스레드만 공유 리소스를 사용합니다. Linux에서 사용되는 3개의 스레드 동기화 메커니즘: Mutexes, Barriers, Condition 변수(condvars).

10.1. Mutexes

Mutex는 상호 제외라는 용어에서 파생됩니다. 상호 제외 오브젝트는 리소스에 대한 액세스를 동기화합니다. 한 번에 하나의 스레드만 뮤텍스를 얻을 수 있도록 하는 메커니즘입니다.

코드의 각 섹션에 대한 직렬 액세스를 만들어 하나의 스레드만 한 번에 코드를 실행하도록 합니다. Mutexes는 뮤지션 특성 개체라고 하는 특성 개체를 사용하여 생성됩니다.Mutexes are created by using an attribute object known as the mutex attribute object. 이는 구현하도록 선택한 POSIX 옵션에 따라 다양한 속성을 포함하는 추상 오브젝트입니다. 특성 오브젝트는 pthread_mutex_t 변수로 정의됩니다. 개체는 뮤지션에 대해 정의된 특성을 저장합니다. pthread_mutex_init(&my_mutex, &my_mutex_attr), pthread_mutexattr_setbust()pthread_mutexattr_getrobust() 함수는 0을 반환합니다. 오류가 발생하면 오류 번호를 반환합니다.

실시간으로 특성 개체를 유지하여 동일한 형식의 더 많은 뮤지션을 초기화하거나 특성 개체를 정리(destroy)할 수 있습니다.In real-time, you can either retain the attribute object to initialize more mutexes of the same type or you can clean up (destroy) the attribute object. 뮤지컬은 두 경우 모두 영향을 받지 않습니다. 뮤텍스에는 표준 및 고급 유형의 뮤지셔너스가 포함됩니다.

표준 뮤추스

실시간 표준 뮤지스트는 비공개, 비재귀, 로비 버스트 및 우선 순위가 아닌 상속 가능 뮤지션입니다. pthread_mutex_t 를 초기화하여 pthread_mutex_init(&my_mutex, &my_mutex_attr) 를 사용하면 표준 뮤지션이 생성됩니다. 표준 Mutex 유형을 사용하는 경우 애플리케이션은 pthreads API 및 RHEL for Real Time 커널에서 제공하는 이점을 활용할 수 없습니다.

고급 뮤지션

추가 기능으로 정의된 뮤지컬을 고급 뮤지션이라고 합니다. 고급 기능에는 우선 순위 상속, 뮤지션의 강력한 동작, 공유 및 개인 뮤지션이 포함됩니다. 예를 들어 강력한 뮤지션의 경우 pthread_mutexattr_setrobust() 함수를 초기화하면 강력한 특성이 설정됩니다. 마찬가지로 PTHREAD_PROCESS_SHARED 특성을 사용하여 스레드가 할당된 메모리에 액세스할 수 있는 경우 모든 스레드가 뮤지션에서 작동할 수 있습니다.Similarly, by using the attribute PTHREAD_PROCESS_SHARED , allows any thread to operate on the mutex, provided the thread has access to its allocated memory. PTHREAD_PROCESS_PRIVATE 속성은 개인 뮤지션을 설정합니다.

Robust 뮤지션이 자동으로 해제되지 않고 수동으로 해제할 때까지 잠길 수 있습니다.

10.2. 장애 발생

경계는 다른 스레드 동기화 방법과 비교할 때 매우 다른 방식으로 작동합니다. 경계선은 모든 스레드와 프로세스가 이 장벽에 도달할 때까지 모든 활성 스레드가 중지되는 코드의 지점을 정의합니다. 경계는 실행 중인 애플리케이션이 실행을 계속하기 전에 모든 스레드가 특정 작업을 완료하도록 해야 하는 경우에 사용됩니다.

장벽 뮤지션은 다음 두 가지 변수를 사용합니다.

  • 첫 번째 변수는 중지 및 장벽의 전달 상태를 기록합니다.
  • 두 번째 변수는 장벽에 진입하는 총 스레드 수를 기록합니다.

장벽은 지정된 수의 스레드가 정의된 장벽에 도달할 때만 전달되도록 상태를 설정합니다. 장벽 상태가 전달되도록 설정되면 스레드와 프로세스가 더 계속 진행됩니다. pthread_barrier_init() 함수는 필요한 리소스를 할당하여 정의된 장벽을 사용하고 attr 속성 개체에서 참조하는 속성으로 초기화합니다.

pthread_barrier_init()pthread_barrier_destroy() 함수는 성공하면 0 값을 반환합니다. 오류가 발생하면 오류 번호가 반환됩니다.

10.3. 상태 변수

실시간으로 조건 변수(condvar)는 진행하기 전에 특정 조건이 달성될 때까지 기다리는 POSIX 스레드 구조입니다. 일반적으로 신호된 조건은 스레드가 다른 스레드와 공유하는 데이터 상태와 관련이 있습니다. 예를 들어 condvar 를 사용하여 데이터 항목을 처리 큐로 신호하고 큐에서 해당 데이터를 처리하기 위해 대기 중인 스레드를 사용할 수 있습니다. pthread_cond_init() 함수를 사용하면 조건 변수를 초기화할 수 있습니다.

pthread_cond_init(), pthread_cond_wait()pthread_cond_signal() 함수는 성공하면 0 값을 반환합니다. 오류가 발생하면 오류 번호를 반환합니다.

10.4. 뮤추스 클래스

언급된 Mutex 옵션은 애플리케이션을 작성하거나 이식할 때 고려할 뮤지션 클래스에 대한 지침을 제공합니다.

Expand
표 10.1. Mutex 옵션
고급 뮤지션설명

공유 뮤지션

여러 스레드가 지정된 시간에 뮤지션을 얻을 수 있도록 공유 액세스를 정의합니다.Defines shared access for multiple threads to acquire a mutex at a given time. 공유 뮤지션은 대기 시간을 만들 수 있습니다. 속성은 PTHREAD_PROCESS_SHARED 입니다.

개인 뮤지션

동일한 프로세스 내에서 생성된 스레드만 뮤텍스에 액세스할 수 있도록 합니다.Ensures that only the threads created within the same process can access the mutex. 속성은 PTHREAD_PROCESS_PRIVATE 입니다.

실시간 우선 순위 상속

우선 순위가 낮은 작업의 우선 순위 수준을 현재 더 높은 우선 순위 작업보다 높게 설정합니다. 작업이 완료되면 리소스를 해제하고 작업이 더 높은 우선 순위 작업을 실행할 수 있도록 원래 우선 순위로 다시 드롭됩니다. 속성은 PTHREAD_PRIO_INHERIT 입니다.

강력한 뮤추스

소유 스레드가 중지될 때 강력한 뮤지를 자동으로 릴리스하도록 설정합니다.Sets the robust mutexes to release automatically when the owning thread would stop. PTHREAD_MUTEX_ROBUST_ NP 문자열의 값 하위 문자열 NP 은 강력한 뮤지션이 POSIX가 아니거나 이식할 수 없음을 나타냅니다.

10.5. 스레드 동기화 함수

언급된 함수 유형 목록과 설명은 실시간 커널의 스레드 동기화 메커니즘에 사용할 기능에 대한 정보를 제공합니다.

Expand
표 10.2. 함수
함수설명

pthread_mutexattr_init(&my_mutex_attr)

attr에서 지정한 특성을 사용하여 뮤지션을 시작합니다.Begins a mutex with attributes specified by attr. attr 이 NULL이면 기본 뮤지션 특성을 적용합니다.

pthread_mutexattr_destroy(&my_mutex_attr)

지정된 뮤지션 개체를 삭제합니다.Deletes the specified mutex object. pthread_mutex_init() 를 사용하여 다시 초기화할 수 있습니다.

pthread_mutexattr_setrobust()

뮤지션의 PTHREAD_MUTEX_ROBUST 특성을 지정합니다. PTHREAD_MUTEX_ROBUST 속성은 뮤지션의 잠금 해제 없이 중지할 수 있는 스레드를 정의합니다. 이 뮤지션을 소유하기 위한 향후 호출은 자동으로 성공하고 EOWNERDEAD 값을 반환하여 이전 뮤지션 소유자가 더 이상 존재하지 않음을 나타냅니다.

pthread_mutexattr_getrobust()

뮤지션의 PTHREAD_MUTEX_ROBUST 특성을 쿼리합니다.

pthread_barrier_init()

특성 개체 attr 을 사용하여 장벽을 사용하고 초기화하는 데 필요한 리소스를 할당합니다. attr 이 NULL이면 기본값을 적용합니다.

pthread_cond_init()

조건 변수를 초기화합니다. cond 인수는 조건 변수 특성 오브젝트 attr 의 특성으로 시작할 오브젝트를 정의합니다. attr 이 NULL이면 기본값을 적용합니다.

pthread_cond_wait()

다른 스레드에서 신호를 수신할 때까지 스레드 실행을 차단합니다. 또한 이 함수에 대한 호출은 차단하기 전에 뮤지션에서 연결된 잠금을 해제합니다.In addition, a call to this function also releases the associated lock on mutex before blocking. cond 인수는 스레드가 차단할 pthread_cond_t 오브젝트를 정의합니다. Mutex 인수는 뮤지션의 차단 해제를 지정합니다.

pthread_cond_signal()

지정된 조건 변수에서 차단되는 스레드 중 하나 이상을 차단합니다. cond 인수는 pthread_cond_t 오브젝트를 사용하여 스레드를 차단 해제합니다.

11장. RHEL for Real Time의 소켓 옵션

실시간 소켓은 UNIX 도메인 및 루프백 장치와 같은 두 프로세스 간 또는 네트워크 소켓과 같은 다른 시스템 간의 데이터 전송 메커니즘입니다.

TCP(Transmission Control Protocol)는 가장 일반적인 전송 프로토콜이며, 종종 일정한 통신이 필요하거나 우선 순위가 낮은 환경에서 소켓을 공동 배치하는 서비스에 대해 일관된 짧은 대기 시간을 달성하는 데 사용됩니다.

새로운 애플리케이션, 하드웨어 기능 및 커널 아키텍처 최적화를 통해 TCP는 변경 사항을 효과적으로 처리할 수 있는 새로운 접근 방식을 도입해야 합니다. 새로운 접근 방식은 불안정한 프로그램 동작을 유발할 수 있습니다. 기본 운영 체제 구성 요소가 변경되면 프로그램 동작이 변경되므로 주의해서 처리해야 합니다.

TCP에서 이러한 동작의 한 예는 작은 버퍼 전송 지연입니다. 이를 통해 하나의 네트워크 패킷으로 전송할 수 있습니다. TCP에 작은 쓰기를 버퍼링하고 한 번에 모두 보내는 것은 일반적으로 잘 작동하지만 대기 시간을 만들 수도 있습니다. 실시간 애플리케이션의 경우 TCP_NODELAY 소켓 옵션은 지연을 비활성화하고 준비된 즉시 작은 쓰기를 보냅니다.

데이터 전송에 대한 관련 소켓 옵션은 TCP_NODELAYTCP_CORK 입니다.

11.1. TCP_NODELAY 소켓 옵션

TCP_NODELAY 소켓 옵션은 나글의 알고리즘을 비활성화합니다. setsockopt sockets API 함수를 사용하여 TCP_NODELAY 를 구성하면 즉시 개별 패킷으로 여러 개의 작은 버퍼 쓰기가 전송됩니다.

보내기 전에 연속 패킷을 빌드하여 여러 논리 관련 버퍼를 단일 패킷으로 전송하면 대기 시간과 성능이 향상됩니다. 또는 메모리 버퍼가 논리적으로 관련이 있지만 연속적이지 않은 경우 I/O 벡터를 만들고 TCP_NODELAY 가 활성화된 소켓에서 writev 를 사용하여 커널에 전달할 수 있습니다.

다음 예제에서는 setsockopt 소켓 API를 통해 TCP_NODELAY 를 활성화하는 방법을 보여줍니다.

int one = 1;
setsockopt(descriptor, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
참고

TCP_NODELAY 를 효과적으로 사용하려면 작고 논리적으로 관련된 버퍼 쓰기를 피하십시오. TCP_NODELAY 를 사용하면 작은 쓰기를 통해 TCP가 개별 패킷으로 여러 버퍼를 보내 전체 성능이 저하될 수 있습니다.

11.2. TCP_CORK 소켓 옵션

TCP_CORK 옵션은 소켓의 모든 데이터 패킷을 수집하고 버퍼가 지정된 제한으로 채워질 때까지 전송하지 않습니다. 이를 통해 애플리케이션은 커널 공간에 패킷을 빌드하고 TCP_CORK 가 비활성화되면 데이터를 보낼 수 있습니다. TCP_CORKsetsocketopt() 함수를 사용하여 소켓 파일 설명자에 설정됩니다. 프로그램을 개발할 때 파일에서 대량 데이터를 보내야하는 경우 sendfile() 함수와 함께 TCP_CORK 를 사용하는 것이 좋습니다.

논리 패킷이 다양한 구성 요소에서 커널에 빌드되면 setsockopt 소켓 API를 사용하여 1 값으로 구성하여 TCP_CORK 를 활성화합니다. 이를 "corking the socket"이라고 합니다. TCP_CORK 는 코크가 적절한 시간에 제거되지 않는 경우 버그가 발생할 수 있습니다.

다음 예제에서는 setsockopt 소켓 API를 통해 TCP_CORK 를 활성화하는 방법을 보여줍니다.

int one = 1;
setsockopt(descriptor, SOL_TCP, TCP_CORK, &one, sizeof(one));

일부 환경에서는 커널이 코크를 제거할 시기를 확인할 수 없는 경우 다음과 같이 수동으로 제거할 수 있습니다.

int zero = 0;
setsockopt(descriptor, SOL_TCP, TCP_CORK, &zero, sizeof(zero));

11.3. 소켓 옵션을 사용하는 프로그램의 예

TCP_NODELAYTCP_CORK 소켓 옵션은 네트워크 연결 동작에 큰 영향을 미칩니다. TCP_NODELAY 는 데이터 패킷을 준비한 즉시 전송할 수 있는 애플리케이션에 대해 나글의 알고리즘을 비활성화합니다. TCP_CORK 를 사용하면 서로 지연 없이 여러 데이터 패킷을 동시에 전송할 수 있습니다.

참고

소켓 옵션(예: TCP_NODELAY )을 활성화하려면 다음 코드로 빌드한 다음 적절한 옵션을 설정합니다.

gcc tcp_nodelay_client.c -o tcp_nodelay_client -lrt

인수 없이 tcp_nodelay_servertcp_nodelay_client 프로그램을 실행하면 클라이언트는 기본 소켓 옵션을 사용합니다. tcp_nodelay_servertcp_nodelay_client 프로그램에 대한 자세한 내용은 Red Hat Knowledgebase 솔루션 TCP 변경으로 인해 작은 버퍼가 사용될 때 대기 시간 성능이 향상됩니다.

예제 프로그램은 이러한 소켓 옵션이 애플리케이션에 미칠 수 있는 성능에 대한 정보를 제공합니다.

클라이언트에 대한 성능 영향

TCP_NODELAYTCP_CORK 소켓 옵션을 사용하지 않고도 작은 버퍼 쓰기를 클라이언트에 보낼 수 있습니다. 인수 없이 실행하는 경우 클라이언트는 기본 소켓 옵션을 사용합니다.

  • 데이터 전송을 시작하려면 서버 TCP 포트를 정의합니다.

    $ ./tcp_nodelay_server 5001

    이 코드는 각각 두 바이트의 15개의 패킷을 전송하고 서버의 응답을 기다립니다. 여기에서 기본 TCP 동작을 채택합니다.

루프백 인터페이스에 대한 성능 영향

소켓 옵션을 활성화하려면 gcc tcp_nodelay_client.c -o tcp_nodelay_client -lrt 를 사용하여 빌드한 다음 적절한 옵션을 설정합니다.

다음 예제에서는 루프백 인터페이스를 사용하여 다음 세 가지 변형을 보여줍니다.

  • 버퍼 쓰기를 즉시 보내려면 TCP_NODELAY 로 구성된 소켓에서 no_delay 옵션을 설정합니다.

    $ ./tcp_nodelay_client localhost --port=5001 --nr_logical_packets=10000 --no_delay --verbose
    
     10000 packets (100 buffers) sent in 4079.655518 ms: 490.237457 bytes/ms using TCP_NODELAY

    TCP는 버퍼를 즉시 전송하여 작은 패킷을 결합하는 알고리즘을 비활성화합니다. 이렇게 하면 성능이 향상되지만 각 논리 패킷에 대해 작은 패킷의 변동이 발생할 수 있습니다.

  • 여러 데이터 패킷을 수집하여 하나의 시스템 호출로 보내려면 TCP_CORK 소켓 옵션을 구성합니다.

    $ /tcp_nodelay_client localhost --port=5001 --nr_logical_packets=10000 --cork --verbose
    
     10000 packets (100 buffers) sent in 669.514221 ms: 2987.240479 bytes/ms using TCP_CORK

    코크 기술을 사용하면 버퍼에서 전체 논리 패킷을 결합하고 전체 네트워크 패킷을 덜 보낼 때 데이터 패킷을 보내는 데 필요한 시간이 크게 줄어듭니다. 적절한 시간에 코르크 를 제거해야 합니다.

    프로그램을 개발할 때 파일에서 대량 데이터를 보내야하는 경우 sendfile() 옵션과 함께 TCP_CORK 를 사용하는 것이 좋습니다.

  • 소켓 옵션을 사용하지 않고 성능을 측정하려면 다음을 수행합니다.

    $ ./tcp_nodelay_client localhost --port=5001 --nr_logical_packets=10000 --verbose
    
     10000 packets (100 buffers) sent in 410403.718750 ms: 4.873250 bytes/ms

    이는 TCP가 버퍼 쓰기를 결합하고 네트워크 패킷에 최적으로 들어갈 수 있는 것보다 더 많은 데이터를 확인하기 위해 대기할 때의 기준 척도입니다.

12장. RHEL for Real Time 스케줄러

RHEL for Real Time은 명령줄 유틸리티를 사용하여 프로세스 구성을 구성하고 모니터링하는 데 도움이 됩니다.

12.1. 스케줄러를 설정하는 chrt 유틸리티

chrt 유틸리티는 스케줄러 정책 및 우선 순위를 확인하고 조정합니다. 원하는 속성으로 새 프로세스를 시작하거나 실행 중인 프로세스의 현재 속성을 변경할 수 있습니다.

chrt 유틸리티는 --pid 또는 -p 옵션을 사용하여 프로세스 ID(PID)를 지정합니다.

chrt 유틸리티는 다음과 같은 정책 옵션을 사용합니다.

  • -f 또는 --fifo: 일정을 Cryostat _FIFO 로 설정합니다.
  • - O 또는 --other: 일정을 Cryostat _OTHER 로 설정합니다.
  • -r 또는 --rr: schedule을 Cryostat _RR 로 설정합니다.
  • -d 또는 --deadline: schedule을 Cryostat _DEADLINE으로 설정합니다.

다음 예제에서는 지정된 프로세스의 특성을 보여줍니다.

# chrt -p 468
pid 468’s current scheduling policy: SCHED_FIFO
pid 468’s current scheduling priority: 85

12.2. 선점 스케줄링

실시간 선점은 나중에 다시 시작할 의도로 실행 중인 작업을 일시적으로 중단하는 메커니즘입니다. 우선 순위가 높은 프로세스가 CPU 사용량을 중단하면 발생합니다. 선점은 성능에 특히 부정적인 영향을 미칠 수 있으며 지속적인 선점은 충돌이라는 상태로 이어질 수 있습니다. 이 문제는 프로세스가 지속적으로 선점되고 프로세스가 완전히 실행되지 않을 때 발생합니다. 작업의 우선 순위를 변경하면 비자발적 선점을 줄이는 데 도움이 될 수 있습니다.

/proc/PID/status 파일의 내용을 확인하여 단일 프로세스에서 발생하는 번거롭고 불필요한 선점을 확인할 수 있습니다. 여기서 PID는 프로세스 식별자입니다.

다음 예제에서는 PID 1000이 있는 프로세스의 선점 상태를 보여줍니다.

# grep voluntary /proc/1000/status
voluntary_ctxt_switches: 194529
nonvoluntary_ctxt_switches: 195338

12.3. 스케줄러 우선 순위에 대한 라이브러리 함수

실시간 프로세스는 다른 라이브러리 호출 세트를 사용하여 정책 및 우선 순위를 제어합니다. 함수에는 sched.h 헤더 파일이 포함되어야 합니다. 기호sched.h 헤더 파일에 정의되어 있어야 합니다.

표에는 실시간 스케줄러의 정책 및 우선 순위를 설정하는 함수가 나열되어 있습니다.

Expand
표 12.1. 실시간 스케줄러를 위한 라이브러리 함수
함수설명

sched_getscheduler()

특정 PID(프로세스 ID)에 대한 스케줄러 정책 검색

sched_setscheduler()

스케줄러 정책 및 기타 매개변수를 설정합니다. 이 함수에는 sched_setscheduler(pid_t pid,int 정책,const struct sched_param *sp)의 매개변수가 필요합니다.

sched_getparam()

스케줄링 정책의 스케줄링 매개 변수를 검색합니다.

sched_setparam()

이미 설정되어 있고 sched_getparam() 함수를 사용하여 확인할 수 있는 스케줄링 정책과 관련된 매개변수를 설정합니다.

sched_get_priority_max()

스케줄링 정책과 연결된 최대 유효한 우선 순위를 반환합니다.

sched_get_priority_min()

스케줄링 정책과 연결된 최소 유효한 우선 순위를 반환합니다.

sched_rr_get_interval()

각 프로세스에 할당된 timeslice 를 표시합니다.

13장. RHEL for Real Time의 시스템 호출

실시간 시스템 호출은 애플리케이션 프로그램에서 커널과 통신하는 데 사용하는 기능입니다. 프로그램에서 커널에서 리소스를 정렬하는 메커니즘입니다.

13.1. sched_yield() function

sched_yield() 함수는 프로세서가 실행 중인 프로세스 이외의 프로세스를 선택하도록 설계되었습니다. 이러한 유형의 요청은 잘못 작성된 애플리케이션 내에서 발행된 경우 실패하기 쉽습니다.

sched_yield() 함수가 실시간 우선순위가 있는 프로세스 내에서 사용하면 예기치 않은 동작을 표시할 수 있습니다. sched_yield() 를 호출하는 프로세스는 동일한 우선 순위로 실행되는 프로세스의 테일로 이동합니다. 동일한 우선 순위에서 다른 프로세스가 실행되지 않으면 sched_yield() 라는 프로세스가 계속 실행됩니다. 해당 프로세스의 우선 순위가 높으면 잠재적으로 사용 중인 루프를 생성하여 머신을 사용할 수 없게 될 수 있습니다.

일반적으로 실시간 프로세스에서 sched_yield() 를 사용하지 마십시오.

13.2. getrusage() 함수

getrusage() 함수는 지정된 프로세스 또는 해당 스레드에서 중요한 정보를 검색합니다. 다음과 같은 정보를 보고합니다.

  • 개인화된 컨텍스트 전환 수입니다.
  • 메이저 및 마이너 페이지 폴트.
  • 사용 중인 메모리 양입니다.

getrusage() 를 사용하면 성능 튜닝 및 디버깅 활동과 관련된 정보를 제공하도록 애플리케이션을 쿼리할 수 있습니다. getrusage()/proc/ 디렉터리에 있는 여러 다른 파일에서 카탈로그해야 하는 정보를 검색하고 애플리케이션의 특정 작업 또는 이벤트와 동기화하기가 어렵습니다.

참고

getrusage() 결과로 채워진 구조에 포함된 모든 필드가 커널에 의해 설정되지는 않습니다. 일부는 호환성을 위해서만 유지됩니다.

14장. RHEL for Real Time의 타이머를 사용하여 스케줄링 대기 시간 측정

rtla- timerlat 툴은 타이머 추적기를 위한 인터페이스입니다. 타이머 모음 추적기는 실시간 스레드의 레이닝 대기 시간 소스를 찾습니다. 타이머 내역 추적기는 실시간 우선 순위를 사용하여 CPU당 커널 스레드를 생성하고 이러한 스레드는 주기적인 타이머를 설정하여 잠자기 상태로 돌아갑니다. 슬림에서 타이머는 정보를 찾아서 수집하며 운영 체제 타이머 대기 시간을 디버깅하는 데 유용합니다. timerlat 추적기에서는 출력을 생성하고 모든 활성화 시 다음 두 행을 출력합니다.

  • 타이머 내역 추적기 에서는 타이머 인터럽트 요청(IRQ) 처리기에서 표시되는 타이머 대기 시간을 주기적으로 출력합니다. 스레드 활성화 전에 hardirq 컨텍스트에 표시되는 첫 번째 출력입니다.
  • 두 번째 출력은 스레드의 타이머 대기 시간입니다. ACTIVATION ID 필드는 해당 스레드 실행에 대한 인터럽트 요청(IRQ) 성능을 표시합니다.

14.1. 스케줄링 대기 시간을 측정하도록 타이머lat 추적 프로그램 구성

추적 시스템의 curret_tracer 파일에 timerlat 을 추가하여 타이머 추적기를 구성할 수 있습니다. current_tracer 파일은 일반적으로 /sys/kernel/tracing 디렉터리에 마운트됩니다. 타이머 내역 추적기는 인터럽트 요청(IRQ)을 측정하고 스레드 대기 시간이 100 마이크로초를 초과하면 분석을 위해 추적 출력을 저장합니다.

프로세스

  1. 현재 추적기를 나열합니다.

    # cat /sys/kernel/tracing/current_tracer
    nop

    no operations (nop)는 기본 추적기입니다.

  2. 추적 시스템의 current_tracer 파일에 timerlat 추적기를 추가합니다.

    # cd /sys/kernel/tracing/
    # echo timerlat > current_tracer
  3. 추적 출력을 생성합니다.

    # cat trace
    # tracer: timerlat

검증

  • 다음 명령을 입력하여 타이머 가 현재 추적기로 활성화되어 있는지 확인합니다.

    # cat /sys/kernel/tracing/current_tracer
    timerlat

14.2. 타이머 추적기 옵션

timerlat 추적기는 osnoise tracer 위에 빌드됩니다. 따라서 /osnoise/config 디렉토리에서 옵션을 설정하여 스레드 스케줄링 대기 시간에 대한 정보를 추적하고 캡처할 수 있습니다.

타이머 수준 옵션

CPU
timerlat 스레드가 실행될 CPU를 설정합니다.
timerlat_period_us
timerlat 스레드의 기간 기간을 마이크로초 단위로 설정합니다.
stop_tracing_us
irq 컨텍스트에서 타이머 대기 시간이 구성된 값보다 크면 시스템 추적을 중지합니다. 0을 작성하면 이 옵션이 비활성화됩니다.
stop_tracing_total_us
총 노이즈가 구성된 값보다 큰 경우 시스템 추적을 중지합니다. 0을 작성하면 이 옵션이 비활성화됩니다.
print_stack
인터럽트 요청(IRQ) 발생 스택을 저장합니다. 스택은 스레드 컨텍스트 이벤트 후 또는 IRQs 처리기가 구성된 값보다 많은 경우 IRQs 발생을 저장합니다.

14.3. rtla-timerlat-top로 타이머 대기 시간 측정

rtla-timerlat-top 추적기에는 타이머 추적기 에서 주기적인 출력 요약이 표시됩니다. 추적기 출력은 또한 각 운영 체제의 노이즈 및 이벤트(예: osnoise ) 및 tracepoints 에 대한 정보를 제공합니다. 이 정보는 -t 옵션을 사용하여 볼 수 있습니다.

프로세스

  • 타이머 대기 시간을 측정하려면 다음을 수행합니다.

    # rtla timerlat top -s 30 -T 30 -t

14.4. rtla 타이머lat 최상위 추적기 옵션

rtla timerlat top --help 명령을 사용하면 rtla-timerlat-top 추적기 에 대한 옵션에 대한 도움말 사용법을 볼 수 있습니다.

timerlat-top-tracer 옵션

-p, --period us
timerlat 추적 기간을 마이크로초 단위로 설정합니다.
-i, --irq us
인터럽트 요청(IRQ) 대기 시간이 마이크로초의 인수보다 큰 경우 추적을 중지합니다.
-t, --thread us
스레드 대기 시간이 마이크로초의 인수보다 큰 경우 추적을 중지합니다.
-t, --trace
중지된 추적을 timerlat_trace.txt 파일에 저장합니다.
-s, --stack us
스레드 대기 시간이 인수보다 크면 인터럽트 요청(IRQ)에 스택 추적을 저장합니다.

15장. 실시간 RHEL에서 rtla-osnoise를 사용하여 스케줄링 대기 시간 측정

초고속 대기 시간은 지연에 대한 허용 오차가 낮은 대량의 데이터 패킷을 처리하기 위해 최적화된 환경입니다. CPU를 포함한 애플리케이션에 배타적 리소스를 제공하는 것은 매우 대기 시간이 짧은 환경에서 널리 사용되는 방법입니다. 예를 들어 NFV(네트워크 기능 가상화) 애플리케이션에서 고성능 네트워크 처리의 경우 단일 애플리케이션에는 작업을 지속적으로 실행하도록 CPU 전원 제한이 설정됩니다.

Linux 커널에는 운영 체제 노이즈(osnoise) 추적기에 대한 인터페이스를 제공하는 실시간 분석(rtla) 툴이 포함되어 있습니다. 운영 체제의 노이즈는 운영 체제 내부의 활동으로 인해 애플리케이션에서 발생하는 간섭입니다. Linux 시스템은 다음과 같은 이유로 노이즈가 발생할 수 있습니다.

  • 마스킹할 수 없는 인터럽트(NMI)
  • 인터럽트 요청(IRQs)
  • 소프트 인터럽트 요청(SoftIRQs)
  • 기타 시스템 스레드 활동
  • 마스크 불가능한 높은 우선 순위 시스템 관리 인터럽트(SMI)와 같은 하드웨어 관련 작업

15.1. rtla-osnoise 추적기

Linux 커널에는 운영 체제 노이즈(osnoise) 추적기에 대한 인터페이스를 제공하는 실시간 분석(rtla) 툴이 포함되어 있습니다. rtla-osnoise 추적기에서는 지정된 기간에 대해 주기적으로 실행되는 스레드를 생성합니다. 기간이 시작될 때 스레드는 인터럽트를 비활성화하고 샘플링을 시작하고 루프에서 시간을 캡처합니다.

rtla-osnoise 추적기에서는 다음과 같은 기능을 제공합니다.

  • CPU가 수신하는 작동 노이즈의 양을 측정합니다.
  • CPU에서 발생하는 운영 체제 노이즈 유형을 나타냅니다.
  • 예기치 않은 결과의 근본 원인을 정의하는 데 도움이 되는 최적화된 추적 보고서를 출력합니다.
  • 각 간섭의 소스에 대한 간섭 카운터를 저장합니다. 마스킹할 수 없는 인터럽트(NMI), 인터럽트 요청(IRQ), 소프트웨어 인터럽트 요청(SoftIRQ) 및 스레드에 대한 중단 카운터는 도구가 이러한 방해에 대한 입력 이벤트를 감지하면 증가합니다.

rtla-osnoise 추적기에서는 기간 종료 시 노이즈 소스에 대한 다음 정보가 포함된 실행 보고서를 출력합니다.

  • 총 노이즈량입니다.
  • 최대 노이즈 양입니다.
  • 스레드에 할당된 CPU의 백분율입니다.
  • 노이즈 소스에 대한 카운터입니다.

15.2. 스케줄링 대기 시간을 측정하도록 rtla-osnoise 추적 프로그램 구성

추적 시스템의 curret_tracer 파일에 osnoise 를 추가하여 rtla-osnoise 추적기를 구성할 수 있습니다. current_tracer 파일은 일반적으로 /sys/kernel/tracing/ 디렉터리에 마운트됩니다. rtla-osnoise 추적기에서는 인터럽트 요청(IRQ)을 측정하고 단일 노이즈 발생을 위해 스레드 대기 시간이 20 마이크로초 이상인 경우 분석을 위해 추적 출력을 저장합니다.

프로세스

  1. 현재 추적기를 나열합니다.

    # cat /sys/kernel/tracing/current_tracer
    nop

    no operations (nop)는 기본 추적기입니다.

  2. 추적 시스템의 current_tracer 파일에 timerlat 추적기를 추가합니다.

    # cd /sys/kernel/tracing/
    # echo osnoise > current_tracer
  3. 추적 출력을 생성합니다.

    # cat trace
    # tracer: osnoise

15.3. 구성에 대한 rtla-osnoise 옵션

rtla-osnoise 추적기에 대한 구성 옵션은 /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() 호출 읽기 사이에 최소 delta를 어댑터로 간주하도록 설정합니다. 0 으로 설정하면tracing_thresh 는 기본값인 5마이크로초를 사용합니다.

15.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
스레드에서 노이즈 및 노이즈 기간을 표시합니다.

15.5. rtla-osnoise 추적기 옵션

osnoise/options 파일에는 rtla-osnoise 추적기 대한 설정 옵션 세트가 포함되어 있습니다.

rtla-osnoise옵션

기본값
옵션을 기본값으로 재설정합니다.
OSNOISE_WORKLOAD
osnoise 워크로드 디스패치를 중지합니다.
PANIC_ON_STOP
tracer가 중지되면 panic() 호출을 설정합니다. 이 옵션은 vmcore 덤프 파일을 캡처합니다.
OSNOISE_PREEMPT_DISABLE
인터럽트 요청(IRQ) 및 하드웨어 관련 노이즈만 허용하는 osnoise 워크로드에 대한 선점을 비활성화합니다.
OSNOISE_IRQ_DISABLE
마스킹할 수 없는 인터럽트(NMI) 및 하드웨어 관련 노이즈만 허용하는 osnoise 워크로드에 대한 인터럽트 요청(IRQ)을 비활성화합니다.

15.6. rtla-osnoise-top 추적기를 사용하여 운영 체제 노이즈 측정

rtla osnoise-top tracer는 유해 소스의 발생 카운터에 대한 정보와 함께 osnoise 추적기의 주기적인 요약을 측정하고 출력합니다.

프로세스

  1. 시스템 노이즈 측정:

    # rtla osnoise top -P F:1 -c 0-3 -r 900000 -d 1M -q

    명령 출력은 실시간 우선 순위, 스레드를 실행하도록 할당된 CPU 및 실행 기간(마이크로초)에 대한 정보가 포함된 주기적인 요약을 표시합니다.

15.7. rtla-osnoise-top 추적기 옵션

rtla osnoise top --help 명령을 사용하면 rtla-osnoise-top 추적기에 사용 가능한 옵션에 대한 도움말 사용량을 볼 수 있습니다.

rtla-osnoise-top옵션

-a, --auto us
자동 추적 모드를 설정합니다. 이 모드는 시스템을 디버깅하는 동안 일반적으로 사용되는 몇 가지 옵션을 설정합니다. 이는 -s us -T 1-t 를 사용하는 것과 동일합니다.
-p, --period us
osnoise tracer 기간을 마이크로초 단위로 설정합니다.
-r, --runtime us
osnoise tracer 런타임을 마이크로초 단위로 설정합니다.
-s, --stop us
단일 샘플이 microseconds의 인수보다 큰 경우 추적을 중지합니다. -t 를 사용하면 명령은 추적을 출력에 저장합니다.
-s, --stop-total us
총 샘플이 microseconds의 인수보다 큰 경우 추적을 중지합니다. -T 를 사용하면 명령은 추적을 출력에 저장합니다.
-t, --threshold us
노이즈로 간주되는 두 시간 사이의 최소 delta를 지정합니다. 기본 임계값은 5입니다.
-q, --quiet
실행 끝에 요약만 출력합니다.
-c, --cpus cpu-list
할당된 cpu-list 에서 샘플 스레드를 실행하도록 osnoise 추적 프로그램을 설정합니다.
-d, --duration time[s|m|h|d]
실행 기간을 설정합니다.
-d, --debug
디버그 정보를 출력합니다.
-t, --trace[=file]
중지된 추적을 [file|osnoise_trace.txt] 파일에 저장합니다.
-e, --event sys:event
trace(-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 추적r 스레드로 설정합니다.
-h, --help
도움말 메뉴를 출력합니다.

16장. 실시간 커널 및 솔루션 예약

실시간 커널에서의 예약은 경우에 따라 발생할 수 있습니다. 제공된 정보를 사용하면 실시간 커널에서 스케줄링 정책, 스케줄러 제한 및 스레드 중단 상태에 대한 문제와 잠재적인 솔루션을 파악할 수 있습니다.

16.1. 실시간 커널의 스케줄링 정책

실시간 스케줄링 정책은 하나의 주요 특성을 공유합니다. 높은 우선 순위 스레드가 스레드 또는 스레드가 I/O를 잠급거나 수행하여 대기할 때까지 실행됩니다.

Cryostat _RR 의 경우 운영 체제는 실행 중인 스레드를 중단하여 동일한 Cryostat _RR 우선순위의 다른 스레드를 실행할 수 있도록 합니다. 이러한 경우 중 하나에서 더 낮은 우선 순위 스레드가 CPU 시간을 얻을 수 있도록 정책을 정의하는 POSIX 사양에 의해 프로비저닝이 이루어지지 않습니다. 실시간 스레드의 이러한 특성은 지정된 CPU의 100%를 단조하는 애플리케이션을 쉽게 작성할 수 있음을 의미합니다. 그러나 이로 인해 운영 체제에 문제가 발생합니다. 예를 들어, 운영 체제는 시스템 전체 및 CPU당 리소스를 모두 관리해야 하며 이러한 리소스를 설명하는 데이터 구조를 주기적으로 검사하고 하우스키핑 활동을 수행해야 합니다. 그러나 코어가 Cryostat _FIFO 스레드에 의해 단조되는 경우 하우스키핑 작업을 수행할 수 없습니다. 결국 전체 시스템이 불안정해지고 잠재적으로 충돌할 수 있습니다.

RHEL for Real Time 커널에서 인터럽트 처리기는 Cryostat _FIFO 우선 순위로 스레드로 실행됩니다. 기본 우선순위는 50입니다. 인터럽트 처리기 스레드보다 높은 Cryostat _FIFO 또는 Cryostat _RR 정책이 있는 cpu-hog 스레드는 인터럽트 처리기가 실행되지 않도록 할 수 있습니다. 이로 인해 프로그램이 인터럽트에 의해 전달되는 데이터 신호를 대기하고 실패하게 됩니다.

16.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 시간을 사용하도록 실시간 작업이 구성됩니다. 이는 실시간 작업이 잘 엔지니어링되어 바인딩되지 않은 폴링 루프와 같은 명확한 경고 사항이 없는 경우에만 적합합니다.

16.3. 실시간 커널에서 스레드 중단

스레드 중단은 스레드가 별표 임계값보다 오래 CPU 실행 대기열에 있고 진행되지 않을 때 발생합니다. 스레드 중단의 일반적인 원인은 CPU에 바인딩된 Cryostat _FIFO 또는 Cryostat _ RR 과 같은 고정 우선 순위의 폴링 애플리케이션을 실행하는 것입니다. 폴링 애플리케이션은 I/O를 차단하지 않으므로 kworkers 와 같은 다른 스레드가 해당 CPU에서 실행되지 않도록 할 수 있습니다.

스레드 중단을 줄이기 위한 초기 시도는 실시간 제한이라고 합니다. 실시간 제한에서 각 CPU에는 실시간이 아닌 작업 전용 실행 시간의 일부가 있습니다. 제한의 기본 설정은 실시간 작업에 대해 CPU의 95%를 사용하고 5%는 비실시간 작업을 위해 예약되어 있습니다. 이 작업은 단일 실시간 작업으로 인해 중단을 유발하지만 CPU에 할당된 실시간 작업이 여러 개 있는 경우 작동하지 않습니다. 다음을 사용하여 문제를 해결할 수 있습니다.

stalld 메커니즘

stalld 메커니즘은 실시간 제한에 대한 대안이며 제한적인 단점을 방지합니다. stalld 는 시스템에서 각 스레드의 상태를 정기적으로 모니터링하고 실행 대기열에 있는 스레드를 실행하지 않고 지정된 시간 동안 찾는 데몬입니다. stalld 는 thread가 Cryostat _DEADLINE 정책을 사용하도록 일시적으로 변경되고 지정된 CPU에서 스레드에 작은 시간을 할당합니다. 그런 다음 스레드가 실행되고 시간 슬라이스를 사용하면 스레드가 원래 스케줄링 정책으로 반환되고 stalld 는 스레드 상태를 계속 모니터링합니다.

하우스키핑 CPU는 모든 데몬, 쉘 프로세스, 커널 스레드, 인터럽트 처리기 및 분리된 CPU에서 디스패치할 수 있는 모든 작업을 실행하는 CPU입니다. 실시간 제한이 비활성화된 하우스키핑 CPU의 경우 stalld 는 기본 워크로드를 실행하는 CPU를 모니터링하고 Cryostat _FIFO 사용량 루프로 CPU를 할당하므로 이전에 정의된 허용 가능한 추가 노이즈에서 필요에 따라 stalled 스레드를 감지하고 스레드 우선 순위를 개선하는 데 도움이 됩니다. 실시간 제한 메커니즘으로 인해 주요 워크로드에서 불합리한 노이즈가 발생하는 경우 stalld 가 선호될 수 있습니다.

stalld 를 사용하면 겨운 스레드를 강화하여 도입 된 노이즈를 더 정확하게 제어할 수 있습니다. 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 파일에 전달하여 제한을 비활성화할 수 있습니다.

법적 공지

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2026 Red Hat
맨 위로 이동