산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial Internet of Things >> 임베디드

최상의 Qt 상태 시스템 성능을 보장하는 방법

응용 프로그램 개발에 Qt를 사용하고 상태 머신을 사용한다면 Qt 상태 머신 프레임워크를 사용하고 있을 가능성이 큽니다. 따라서 일반 C++ 또는 SCXML을 사용하여 상태 시스템을 정의합니다. 다른 접근 방식은 상태 머신 다이어그램에서 C++ 코드를 생성하는 것입니다. 이 문서에서는 기능, 적용 가능성 및 성능을 고려하여 이러한 접근 방식을 비교합니다.

나는 당신이 소프트웨어 개발자로서 이미 수많은 switch-case 문을 다소 복잡하게 구현했다고 확신합니다. 이것은 적어도 나에게는 사실이며 이 스위치 케이스 코딩의 대부분은 본질적으로 다양한 상태 머신을 구현하는 것 외에는 아무것도 아닙니다. 이것은 원하는 프로그래밍 언어 외에 다른 것이 없는 경우 상태 머신 프로그래밍을 시작하는 가장 쉬운 방법입니다. 시작은 쉽지만 상태 머신의 복잡성이 증가함에 따라 이러한 코드는 유지 관리가 어려워집니다. 결국 이런 식으로 상태 머신을 수동으로 계속 구현하고 싶지 않다는 확신을 갖게 될 것입니다. (그런데 – 나는 당신이 상태 머신이 무엇인지 알고 있다고 가정합니다.)

상태 머신 구현

상태 머신을 구현하는 다양한 대안이 있습니다. 더 나은 방법 중 하나는 특히 C++와 같은 객체 지향 프로그래밍 언어를 사용할 때 상태 패턴을 적용하는 것입니다. 이 접근 방식은 상태 클래스와 종종 전환 클래스도 사용합니다. 그런 다음 상태 클래스의 인스턴스를 만들고 전환 클래스의 인스턴스를 사용하여 연결하여 상태 머신을 정의합니다. 이 경우 프레임워크는 코드 크기와 구현 노력을 줄이는 데 많은 도움이 됩니다.

Qt 상태 머신 프레임워크가 좋은 예입니다. 이 API를 사용하면 컴팩트 코드를 사용하여 상태 머신을 "구성"할 수 있습니다. 상태 머신 실행 의미론의 세부사항은 프레임워크에 의해 이미 구현되어 있으므로 신경 쓸 필요가 없습니다. 여전히 코드를 작성해야 하며 상태 시스템이 더 복잡해지고 수십 또는 수백 개의 상태가 포함되므로 개요를 파악하기가 정말 어려워집니다. 그림은 천 단어의 가치가 있으며 잘 알려진 상태 다이어그램 개념은 이러한 제약을 극복하는 데 도움이 됩니다. Qt 자체는 W3C 표준인 SCXML(State Chart XML)을 지원합니다. 손으로 XML을 작성하는 것은 재미가 없기 때문에Qt Creator 간단한 그래픽 상태 차트 편집기도 포함되어 있습니다.

구체적인 구현 방식과 상관없이 그래픽 구문을 사용하는 것이 상태 머신을 편집하고 이해하는 데 가장 좋은 선택입니다. 이러한 그래픽 모델은 SCXML과 같은 언어로 텍스트로 표현될 수 있을 뿐만 아니라 일반 C++의 스위치 케이스 기반 상태 기계 또는 QStateMachine. 이러한 변환을 수행하는 도구를 사용하면 상태 기계 코드를 손으로 작성하는 고통을 피할 수 있습니다. 세 가지 구현 방식을 모두 동일한 사용성 수준으로 끌어 올립니다. 그럼에도 불구하고 구현은 여전히 ​​근본적으로 다릅니다. 이 문서는 런타임 동작과 특히 성능을 비교하는 것에 관한 것입니다.


Unsplash의 Austris Augusts의 UnsplashPhoto

경쟁사

그렇다면 성능은 어떨까요? 필요한 CPU 주기와 관련하여 사용 가능한 접근 방식은 어떻게 다릅니까? 구체적인 수치를 얻기 위해 성능 테스트 제품군을 설정했습니다. 첫 번째 부분에서는 다양한 구현 전략을 비교합니다. 경쟁업체는 다음과 같습니다.

<올>
  • SCXML 인터프리터 – 테스트 상태 머신은 SCXML을 사용하여 정의되고 Qt의 QSCXMLStateMachine에 의해 실행됩니다. 수업.
  • 상태 패턴 – 테스트 상태 시스템은 QStateMachine을 사용하여 구현됩니다. 수업.
  • 일반 C++ 코드 – 테스트 상태 시스템은 기본적인 스위치 케이스 기반 접근 방식을 적용하는 C++ 클래스에 의해 구현됩니다.
  • 참고:이 예제에 대한 코드는 여기에서 찾을 수 있습니다.

    처음 두 가지 변형은 신호 및 슬롯과 같은 Qt 개념의 사용과 Qt 이벤트 대기열의 사용을 의미하지만 일반 C++ 구현에는 이 인프라가 필요하지 않습니다. 접근 방식을 더 비교 가능하게 하기 위해 테스트 스위트에는 두 가지 테스트 시나리오가 더 포함되어 있습니다.

    이를 통해 한편으로는 신호 및 슬롯 사용과 QEvents 사용의 영향을 비교할 수 있습니다. 반면에 상태 머신 실행 코드는 모든 경우에 동일하지만 단지 다르게 래핑되기 때문에 일반 C++ 구현과 비교합니다.

    테스트 상태 머신

    5명의 경쟁자를 모두 테스트하기 위해 나는 그림 1과 같은 상태 머신을 정의했습니다. 기본 테스트 시나리오의 경우 1입니다.


    그림 1:YAKINDU Statechart 도구로 만든 테스트 상태 머신. (출처:저자)

    테스트 상태 머신은 단순한 플랫 상태 머신입니다. 6가지 상태를 정의합니다. A F로 상태를 순환합니다. 두 개의 입력 이벤트 e1e2 상태 전환을 교대로 트리거하는 정의됩니다. 상태 전환이 발생하면 간단한 작업도 실행됩니다. 각 전환 작업은 x라는 상태 차트 변수에 10을 추가하기만 하면 됩니다. . F 상태에서 전환 A로 추가로 out을 발생(또는 방출)합니다. 이벤트 o .


    그림 2:Qt Creator의 SCXML 모델인 테스트 상태 머신. (출처:저자)

    이 상태 머신은 SCXML 생성을 지원하는 YAKIDU Statechart Tools를 사용하여 정의되었습니다. 이 SCXML은 Qt 프로젝트에 추가할 수 있고 Qt Creator에서 편집할 수 있습니다. 그림에서 볼 수 있듯이. 도 2에 도시된 바와 같이, 상태 머신은 도 2에 도시된 것과 동일한 구조를 갖는다. 1이지만 전환 작업과 같은 일부 세부 사항은 Qt Creator에서 볼 수 없습니다. YAKINDU Statechart 도구는 몇 가지 더 많은 이점을 제공하지만 여기에서 논의하지 않겠습니다.

    여기서 더 중요한 것은 YAKIDU Statechart Tools가 일반 스위치 케이스 기반 C++ 상태 머신 클래스도 생성할 수 있다는 사실입니다. 또한 신호 및 슬롯이 있는 Qt 지원 클래스를 생성하는 옵션을 제공하므로 편리합니다. 이 도구를 사용하여 QStateMachine을 사용하여 상태 패턴 기반 상태 머신을 구현하기만 하면 되었습니다. 손으로. 해당 변종에 사용할 수 있는 코드 생성기가 없었습니다. 그럼에도 불구하고 단일 상태 차트 정의를 사용하여 성능 테스트를 위해 의미적으로 동일한 상태 머신을 얻는 동시에 구현 노력을 많이 절약할 수 있었습니다.

    모든 테스트 케이스는 동일한 체계를 따릅니다. 개별 이벤트를 처리하는 데 걸리는 평균 시간을 측정하고 싶었기 때문에 각 테스트는 단일 상태 루프의 백만 반복을 캡처했습니다. 각 상태 루프는 모든 상태를 방문하고 모든 전환 및 전환 작업을 처리하는 데 필요한 모든 이벤트를 수행합니다. 따라서 상태 루프는 상태 A로 시작하고 끝납니다. 활동 중입니다. 즉, 각 테스트 사례에 대해 in 이벤트 및 전환 작업 및 100만 아웃 연결된 전환 작업이 있는 이벤트가 처리됩니다. 테스트는 명령줄 응용 프로그램으로 실행되었으며 반복 시간을 단일 배치로 기록했습니다. 이벤트당 시간 소비는 측정된 시간을 in 횟수의 합으로 나누어 간단히 결정할 수 있습니다. 이벤트 및 아웃 이벤트. 여러 번 테스트를 수행하여 가장 낮은 값의 측정 결과를 선택했습니다.

    테스트는 Core i7 Quad Core CPU 2.4GHz가 장착된 이전(2014년 중반) MacBook Pro에서 디버그 정보 없이 최적화된 코드를 사용하여 수행되었습니다. 물론 구체적인 숫자는 시스템과 운영 체제에 따라 다릅니다. 그러나 서로 다른 구현 접근 방식을 비교하고 싶었기 때문에 이것은 관련이 없습니다. 이러한 상대적인 차이는 다른 하드웨어 및 OS 플랫폼에서 비교할 수 있습니다.

    실적 수치를 살펴보겠습니다.

    예 – 거의 모든 사람이 일반 C++ 구현이 다른 대안보다 빠를 것이라고 예상했을 것이라고 생각합니다. 하지만 그 차이의 크기는 정말 놀랍습니다.


    그림 3:단일 이벤트 처리 시간 비교. (출처:저자)

    일반 C++를 사용하여 단일 이벤트를 처리하는 데 평균 7나노초가 소요되었습니다. SCXML을 사용하는 데는 33,850나노초가 필요했습니다. 이는 약 4800의 요소이며 엄청난 차이입니다! 비교를 위해 빛은 10km 이상을 이동하는 반면 SCXML 상태 시스템은 단일 전환만 처리하지만 일반 C++ 상태 시스템의 동일한 전환은 빛이 2미터 이상을 이동하는 데 너무 많은 시간을 남깁니다. 이는 CPU 주기 및 에너지 소비에 대해 매우 다른 규모의 차수를 의미합니다.

    물론 구체적인 수치는 기계와 사용된 테스트 절차에 따라 다릅니다. 이 주제는 나중에 다루겠습니다. 그러나 먼저 다른 숫자에 대해 논의합시다. 처음 세 가지 테스트 시나리오에는 모두 동일한 상태 전환 논리가 포함되어 있습니다. 이 논리는 YAKINDU Statechart Tools에서 생성되었지만 각각 다른 방식으로 마무리되었습니다.

    직접 연결을 사용할 때 이벤트 처리를 위해 신호와 슬롯을 사용하는 데 평균 72ns가 소요되었습니다. 따라서 이 메커니즘은 실제 상태 머신 논리와 비교하여 ~90%의 최소 오버헤드를 부과합니다. 이 시점에서 신호와 슬롯을 사용하면 애플리케이션이 느려진다고 주장하고 싶지 않습니다. 대신 상태 머신의 일반 코드 구현이 매우 빠르다라고 주장하고 싶습니다. .

    이것을 세 번째 시나리오와 비교하면 이벤트 대기열을 사용하여 발생하는 성능 오버헤드에 대한 좋은 인상을 줍니다. 이 시나리오에서 모든 상태 차트 이벤트는 이벤트 대기열을 통해 라우팅됩니다. 이벤트당 731ns로 신호 및 슬롯에 비해 ~10배, 일반 C++에 비해 ~100배 소요됩니다.

    비슷한 오버헤드가 "일반 QStateMachine " 및 "SCXML 상태 머신" – 둘 다 활성 이벤트 대기열이 필요합니다. 따라서 가정된 이벤트 큐 오버헤드를 이벤트당 5200ns에서 빼면 QStateMachine의 대략적인 시간 소비를 얻습니다. 이벤트당 4500ns의 프레임워크. 일반 코드 접근 방식과 비교할 때 QStateMachine 기반 상태 머신 구현은 느립니다. 이는 일반 C++ 코드 구현과 비교하여 약 635배입니다.

    마지막으로 SCXML 인터프리터를 살펴보겠습니다. 여기에는 JavaScript 코드 해석이 포함되며 ~7의 또 다른 요소가 추가됩니다. 일반 코드 접근 방식과 비교할 때 SCXML 기반 상태 머신 구현은 매우 느립니다.

    계층 및 직교 상태 머신은 어떻습니까?

    지금까지 간단한 평면 상태 머신에 대해 설명했습니다. 그러나 상태 차트는 훨씬 더 많은 기능을 제공하며 가장 중요한 두 가지 구조적 기능은 계층 구조와 직교성입니다. 그렇다면 이러한 기능을 사용하면 상태 머신 런타임에 어떤 영향을 미칠까요?

    먼저 계층 구조의 영향을 측정하기 위해 프로파일링할 상태 머신의 계층적 변형을 정의했습니다(그림 1 참조). 4.


    그림 4:계층적 테스트 상태 차트. (출처:저자)

    플랫 상태 머신과 정확히 동일한 동작을 제공하지만 일부 복합 상태를 추가합니다. 기능은 동일하게 유지하되 구조만 변경하면 구조적 변형이 포함하는 오버헤드가 어느 정도인지 알 수 있습니다.

    둘째, 직교성의 영향을 측정하기 위해 평면 상태 머신을 4개의 직교 영역 형태로 복제하였다. 그들은 모두 정확히 동일한 기능을 가지고 있습니다. 따라서 결과 상태 머신(그림 5 참조)은 단순 상태 머신이 수행하는 작업의 4배를 수행합니다.


    그림 5:직교 테스트 상태 차트. (출처:저자)

    프로파일링을 위해 가장 빠르고 느린 변형인 일반 C++ 및 SCXML 구현을 선택했습니다. 그림의 다이어그램. 6은 결과를 보여준다. 상태 차트에서 계층 구조를 사용하는 것이 두 구현 변형 모두에서 측정 가능한 성능 영향을 미치지 않는다는 점은 매우 고무적입니다.


    그림 6:계층 구조 및 직교성의 성능 영향. (출처:저자)

    또 다른 긍정적인 결과는 직교성을 사용하는 것도 부정적인 영향을 미치지 않는다는 것입니다. 반대로, 4배의 작업을 수행하기 위해 처리 시간의 4배 이상을 예상할 수 있지만 ~2.4 및 ~3.1 인자를 사용한 런타임의 효과적인 증가는 4보다 훨씬 작습니다.

    왜 이런 일이 발생합니까? 그 이유는 개별 상태 및 이벤트 처리와 독립적인 상태 머신 처리의 일반적인 부분이 있기 때문입니다. 이 부분은 일반 C++ 상태 시스템의 경우 52%(또는 이벤트당 3.5ns)가 소요되는 반면 SCXML의 경우 28%(또는 이벤트당 9300ns)가 소요됩니다. 마지막으로, SCXML에 비해 생성된 C++ 코드를 사용할 때 직교 상태는 영향이 적습니다.

    결론

    일반 C++는 모든 대안보다 훨씬 더 효율적입니다. 신호 및 슬롯 또는 Qt 이벤트 대기열을 사용하면 복잡한 상태 머신 응용 프로그램을 쉽게 구현하고 유지 관리할 수 있는 프레임워크 메커니즘입니다. Qt 상태 머신 프레임워크에는 이러한 메커니즘이 모두 필요합니다. 생성된 C++ 코드를 사용하여 선택할 수 있습니다.

    많은 시나리오, 특히 대화형 시나리오에서 SCXML 상태 머신도 충분히 빠르며 런타임에 상태 차트 정의를 전환하여 동작을 구성 가능하게 하여 더 많은 유연성을 제공할 수 있습니다.


    임베디드

    1. 최고의 보석 디자인 CAD 소프트웨어를 선택하는 방법
    2. 최고의 CNC 브랜드
    3. 적합한 CNC 기계를 선택하는 방법
    4. 창고에서 비상 사태 대비를 보장하는 방법
    5. 기술 직원의 성과를 모니터링하는 방법은 무엇입니까?
    6. 최고의 풍력 터빈 브레이크를 선택하는 방법
    7. 올바른 포장 기계를 선택하는 방법
    8. 적절한 워터젯 절단기를 선택하는 방법
    9. 최고의 판금 접는 기계를 선택하는 방법
    10. 최고의 잠수정 펌프를 선택하는 방법?