실시간 시스템에서는 정해진 시간 내에 작업을 완료해야 하는 요구사항이 매우 중요하다. 여기에서는 Yocto 프로젝트를 통해 개발한 실시간 시스템의 성능을 분석하고 테스트하는 방법을 다룬다.

실시간 성능 측정 지표

지연 시간(Latency)

지연 시간은 요청이 들어온 시점부터 작업이 완료되는 시점까지의 시간이다. 이는 실시간 시스템에서 가장 중요한 성능 지표 중 하나이다.

스케줄링 시간(Scheduling Time)

스케줄링 시간은 작업이 예약되어 실행되기까지 걸리는 시간이다. 높은 우선순위 작업이 적절히 스케줄되는지 확인하는 데 사용된다.

반응 시간(Response Time)

반응 시간은 시스템이 외부 이벤트에 반응하는 시간이다. 이는 하드 리얼타임 시스템에서 매우 중요하다.

성능 분석 도구

cyclictest

cyclictest는 리눅스 시스템에서 실시간 성능을 평가하는 데 널리 사용되는 도구이다. 이 도구는 주기적인 타이머로 지연 시간을 측정한다.

cyclictest -l100000 -m -Sp99

위 명령어는 100,000회 반복 측정을 수행하며, 높은 우선순위(99)로 실행한다. 백그라운드 프로세스를 최소화하기 위해 메모리 락(-m 옵션)을 사용한다.

latencytop

latencytop은 시스템의 지연 시간 문제를 분석하는 도구이다. 지연 시간의 원인을 시각적으로 표시하여 최적화 지점을 찾는 데 도움을 준다.

latencytop

이 명령어는 실시간으로 시스템 지연 문제를 표시한다.

테스트 환경 설정

고정된 CPU 주파수 설정

CPU 주파수가 동적으로 변하면 실시간 성능에 영향을 미칠 수 있으므로, 고정된 주파수로 설정하는 것이 좋다. 이를 위해 cpufreq 도구를 사용할 수 있다.

cpufreq-set -g performance

커널 설정

커널 설정은 실시간 성능에 큰 영향을 미친다. Yocto 빌드 시 다음과 같은 커널 프리셋을 적용할 수 있다:

CONFIG_PREEMPT_RT_FULL=y
CONFIG_NO_HZ_FULL=y
CONFIG_HZ_PERIODIC=y

프로파일링 및 모니터링

perf

perf는 리눅스 커널에서 제공하는 성능 분석 도구로, 다양한 성능 이벤트를 측정할 수 있다.

perf stat -e cycles,instructions -p <PID>

이 명령어는 특정 프로세스(PID)의 CPU 사이클과 명령어 수를 측정한다.

ftrace

ftrace는 리눅스 커널 내부 이벤트를 추적하는 데 사용되는 강력한 도구이다.

echo function_graph > /sys/kernel/debug/tracing/current_tracer

이 설정은 함수 호출 그래프를 기록하여 함수 간 호출 관계를 시각적으로 분석할 수 있게 한다.

실시간 시스템 최적화

스케줄러 설정

리눅스 커널에는 여러 스케줄러가 있으며, 실시간 애플리케이션에서는 특히 PREEMPT_RT 스케줄러를 사용해 높은 정밀도의 우선순위 스케줄링을 제공한다. 이를 통해 항시 실시간 성능을 보장할 수 있다.

CONFIG_PREEMPT=y
CONFIG_PREEMPT_RT_BASE=y

이외에도 아래와 같은 기타 세부적인 설정을 확인하고 조정할 필요가 있다:

실시간 애플리케이션 작성

우선순위 설계

실시간 애플리케이션에서 각 작업의 우선순위를 적절히 설정하는 것은 필수적이다. 높은 우선순위 작업은 즉각적으로 처리되어야 하는 반면, 낮은 우선순위 작업은 그 이후에 처리된다.

메모리 관리

메모리 할당이 실시간 시스템의 성능을 저하시키는 주요 요인이 될 수 있기 때문에, 동적 메모리 할당을 최소화하고 고정 메모리 사용을 고려해야 한다.

타이머

정밀한 타이머를 사용해 이벤트 스케줄링을 정확히 관리한다. clock_nanosleep()과 같은 고정밀 타이머 API를 이용해 시간을 측정하고 대기 기능을 구현하는 것이 좋다.

실시간 네트워크 설정

네트워크 통신도 실시간 시스템 성능에 중대한 영향을 미칠 수 있다. RT 커널을 적용한 리눅스에서도 네트워크 관련 최적화가 필요하다.

sudo ethtool -C eth0 rx-usecs 0

이 명령어는 네트워크 인터페이스에 걸린 느린 인터럽트 수를 줄여 실시간 성능을 향상시킨다.

예제

다음은 실시간 태스크를 수행하는 간단한 예제이다. 이 예제에서는 cyclictest를 사용해 주기적인 작업을 평가한다:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>

void *real_time_task(void *arg) {
    struct timespec time;
    clock_gettime(CLOCK_MONOTONIC, &time);

    while (1) {
        time.tv_nsec += 1000000; // 1ms 주기
        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &time, NULL);

        // 실시간 작업 수행
        printf("Real-time task executed\n");
    }

    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, real_time_task, NULL);
    pthread_join(thread, NULL);

    return 0;
}

이 장에서는 Yocto 프로젝트를 사용하여 실시간 시스템을 설계하고 구현하는 방법을 다루었다. 성능 측정, 분석, 최적화 및 실제 예제까지 포함해 높은 신뢰도의 실시간 시스템을 구축하는 데 필요한 모든 핵심 개념과 도구를 설명하였다.