데이터 참조를 이용한 메모리 축소

개요

NI LabVIEW는 소프트웨어 개발 시 수동으로 메모리를 관리해야 하는 필요성을 만족시킵니다. LabVIEW 컴파일러는 코드를 분석하여 성능을 최적화하고 필요한 메모리 양을 줄이는 방법을 결정합니다. 하지만 메모리 할당에 대해 좀 더 세부적으로 컨트롤하기 원하는 고급 사용자들은 LabVIEW 2009의 데이터에 참조를 생성합니다.

내용

배경

일반적으로 LabVIEW에서 와이어의 분리는 데이터 복사본을 생성합니다. 두 개의 분리된 와이어가 값을 수정하거나 다른 와이어가 원래 값을 사용하여 끝내기 전에 수정하는 것이 가능한 것입니다. LabVIEW의 “Show Buffer Allocations” 옵션을 사용하여 컴파일러가 추가 메모리를 할당하는 위치를 보여줍니다.

기본 예제

New Data Value Reference 노드는 데이터를 입력으로 이용하고 데이터에 참조를 생성합니다. 데이터가 선택되어 사용되면 복사가 여전히 발생한다는 것을 참고합니다.

그림 1. New Data Value Reference 노드는 데이터에 참조를 생성함으로써 연재 방식으로 데이터를 전송하고 접근하는데 사용할 수 있습니다.

새로운 두 개의 노드는 참조에서 불러온 데이터를 사용하고 원래 메모리 위치로 대체하기 위해서In Place Element Structure에서 사용 가능하고며, 여러 개의 In Place Element Structure를 사용할 경우에는, 함수를 블록킹하여 경합 조건을 방지할수 있도록 한 번에 한번만 참조 데이터를 사용하도록 해야 합니다.

그림 2. 본 VI 스니핏은 기능이 사용되는 방법을 나타내는 예제입니다. 본 예제를 직접 실행해보고 싶을 경우 이미지를 블록 다이어그램으로 드래그합니다.

본 다이어그램의 이해를 돕고자 아래 이미지에 나타난 것처럼 개별 구성요소를 살펴보겠습니다.

  1. 참조가 생성되는 데이터의 값은 5입니다.
  2. New Data Value Reference.vi는 데이터의 비트에 대한 refnum을 생성합니다.
  3. 본 예제는 데이터 참조에 대해 상수가 어떻게 나타나는지 보여줍니다.
  4. In Place Element Structure는 Data Value Reference Read/Write에 대한 한 쌍의 노드를 각각 가지고 있습니다. 본 구조는 끝나고 데이터가 재 참조될 때까지 동일한 참조를 사용하는 기타 구조의 실행을 블록킹합니다.
  5. Data Value Reference Read 노드의 에러 출력 와이어는 refnum이 무효할 때 “True”입니다. 또한 Wire Value Reference Node에서의 노력을 수신하게 되어 이 에러들을 병합할 필요가 없습니다.
  6. Delete Data Value Reference.vi는 refnum의 수명을 종료시키며 최종으로 알고 있는 값을 반환합니다.
  7. 본 예제는 프런트 패널 인디케이터에 대한 터미널입니다.

에러 핸들

동시에 획득할 필요가 있는 여러 참조가 있을 경우, LabVIEW는 모든 참조가 수집될 때까지 구조 경계를 기다립니다. 참조 중에서 부적합한 refnum이 있을 경우 어떠한 작업을 하는지 알기 전에는 모든 에러를 함께 병합해야 합니다.

클래스로 참조 사용링

클래스를 포함한 어떠한 데이터 유형으로도 데이터 참조를 사용할 수 있습니다. LabVIEW 클래스는 계층적 관계를 가지고 있으며 클래스에 대한 참조는 이 계층을 모방합니다. 즉, 패런트(parent) 클래스 참조를 기대하는 subVI는 차일드(child) 클래스 참조를 통과할 수 있습니다.

LabVIEW 클래스의 설정 옵션은 참조의 생성과 제거를 클래스의 멤버 VI로 제한하는 기능을 제공합니다. 클래스에 대한 참조가 기타 VI의 다이어그램에서의 유형을 직면할 때는 언제나 적합한 초기화 방식을 통해 정의되는 것을 보장할 수 있습니다.

그림 3. LabVIEW 클래스에 대한 프로퍼티 대화상자에서 클래스에 대한 참조의 생성과 제거를 제한할 수 있습니다.

멤버 VI가 클래스에 대한 참조를 생성하도록 클래스가 표시되어 있다면 New Data Reference 함수는 기타 VI의 다이어그램에 클래스 유형에 대한 참조를 생성하려고 할 경우 간단히 나뉘게 됩니다(기본적으로 활성화되어 있음). 클래스의 클러스터에 대한 참조나 클래스의 어레이는 제한되지 않습니다.

런타임에서 참조의 유형을 반드시 유지해야 하는데, 이는 데이터 값을 교환해서는 안됨을 나타냅니다. LabVIEW는 Preserve Run-Time Class.vi 어근을 이용하여 런타님 유형 일관성을 보장함으로써 두 개의 값을 스와핑하는 데 사용할 수 있습니다. 기초 객체를 변경하도록 허용하는 클래스 참조가 필요할 경우 클래스의 클러스터에 대한 참조를 생성합니다. 이렇게 하면 계층 캐스팅 비용으로 값을 스와핑하는 기능을 제공받게 됩니다.

그림 4. “Preserve Run-Time Class.vi”는 다른 참조의 값들을 참조하는 기능을 제공합니다.

두 번째 옵션은 패런트 클래스가 모든 하위 유형에 대한 참조를 위한 베타적 팩토리(factory)가 되며, 기본적으로 비활성화되어 있습니다. 이 제한은 클래스 자체에 대한 참조를 위한 제한과 동일하게 작동합니다.

차일드 클래스에 대한 데이터 refnum을 가지고 있을 경우 To More Generic.vi를 사용하여 패런트 클래스 참조로 업캐스팅할(upcast) 수 있습니다. 마찬가지로 To More Specific.vi를 나중에 사용하여 참조를 원래 유형으로 다시 가져올 수 있습니다. Ref-to-child-class 와이어를 ref-to-parent-class 터미널로 와이어 연결 시 강제 실행 점(coercion dot)을 업캐스팅합니다.