큰 데이터 세트에 대한 메모리 관리
- 업데이트 날짜:2025-04-04
- 6분 (읽기 시간)
LabVIEW는 자동으로 메모리 할당을 처리합니다. 자동적인 프로세스이기 때문에, LabVIEW에서 데이터를 안전하게 처리하려면 사전에 주의를 기울여야 합니다. 이는 LabVIEW가 자주 데이터를 복사해야 한다는 것을 의미합니다. 프로그램에 큰 데이터 세트를 다루는 경우, 잦은 대규모 데이터 복사는 메모리 부족 에러를 야기할 수 있습니다. 다음 가이드라인에 따라 메모리 관련 문제를 방지하고 프로그램에서 큰 데이터 세트를 처리하는 과정을 최적화하십시오.
큰 데이터 세트 복사본 개수 줄이기
LabVIEW는 데이터 흐름 언어이기 때문에, VI가 더 많은 데이터를 필요로 할 때, 한 개의 와이어가 두 개의 와이어로 될 때처럼 복사본을 생성합니다. LabVIEW는 통상적으로 언제 새 복사본을 만들어야 하는지 가늠할 수 있지만, 가늠이 불가능한 경우에는 만약의 경우에 대비해서 복사본을 만듭니다.
![]() | 노트 LabVIEW Real-time Module을 사용하는 경우, 메모리 복사본은 Real-time 어플리케이션의 결정성에 영향을 미칩니다. |
버퍼 할당 보이기 윈도우를 사용하여 LabVIEW가 어디에 메모리를 할당하는지 구분할 수 있습니다. 이 윈도우는 데이터 버퍼를 구분해내며, LabVIEW는 이 데이터 버퍼를 사용하여 데이터의 복사본을 저장합니다.
다음의 가이드라인을 따라 LabVIEW가 만들어야 하는 복사본의 개수를 줄이십시오.
![]() | 노트 다음의 팁은 좋은 LabVIEW 디자인 사례에 있는 내용과 상충될 수도 있으며, 비정상적으로 큰 데이터 세트 작업을 할 때 메모리의 소모를 줄이는 용도로만 활용하는 것이 좋습니다. |
- 가능한 가장 작은 데이터 타입을 사용합니다. 예를 들어, 배정도 부동소수 대신에 16-비트 정수를 사용합니다.
- 단순한 배열을 사용합니다. LabVIEW는 웨이브폼 또는 다이나믹 데이터에서의 프로세스를 위해 데이터 배열을 추출할 때 데이터 복사본을 추가적으로 하나 더 만듭니다.
- 큰 블록다이어그램 또는 인라인 SubVI를 생성하여 오버헤드를 줄입니다. LabVIEW는 SubVI를 호출할 때 데이터의 복사본을 생성하므로, SubVI를 호출하는 것을 피하십시오.
- SubVI를 통해 데이터를 경로를 설정할 경우에 블록다이어그램 터미널들이 구조나 루프의 밖에 위치하도록 하십시오. LabVIEW는 터미널이 케이스 구조 또는 루프 안에 있을 때 더 많은 데이터 복사본을 생성합니다.
- 필요한 경우를 제외하면, 가능한 한 데이터가 루프를 통과하지 않도록 주의합니다. 데이터가 루프를 통과해야 하는 경우, 터널 대신 시프트 레지스터를 사용합니다. 터널을 사용하는 경우, LabVIEW는 루프가 반복될 때마다 매번 데이터 복사본을 만듭니다.
- 가능한 경우, 필수 입력을 사용합니다. LabVIEW는 기본값을 생성할 때 데이터 복사본을 생성합니다.
- 플랫 시퀀스 구조 대신에 In Place 원소 구조를 사용합니다.
![]() | 팁 최신 LabVIEW 버전이 자동으로 만드는 복사본의 개수는 이전 버전에 비해 적습니다. 따라서 최신 LabVIEW 버전일수록 큰 데이터 처리 성능이 좋습니다. |
큰 데이터 세트 전송하기
데이터 복사본이 생성되는 것을 막을 수 없을 때에는 각 복사본의 크기를 더 작게 만드는 방법이 있습니다. 이를 위해, 데이터를 다른 위치로 전송할 때 큰 데이터 세트를 더 작은 세트로 나눌 수 있습니다. 이 방법은 그룹으로 나누기(chunking)라고도 불립니다. 데이터를 더 작을 그룹으로 나눌 때 LabVIEW가 만드는 복사본은 메모리의 사용을 저해하지 않습니다. 복사본 자체는 작업량 자체에 부정적인 영향을 미치기 때문에, 그래도 복사본을 최소화하는 것이 권장됩니다. 다음의 예는 이와 관련된 개념을 설명해주고 있습니다.
512 MB의 데이터를 디스크에 저장해야 합니다. 단 한번의 호출로 모든 데이터를 불러와서 디스크에 저장할 수 있습니다. 하지만, 복사본의 개수를 1 개로 최소화하더라도, 원본 데이터와 하나의 추가 복사본을 전송하고 있는 것입니다. 즉, LabVIEW로부터 1 GB의 메모리를 요청하는 것입니다. 따라서, 한 번에 500 KB 씩 데이터를 가져오도록 반복적인 루프를 만들어서 디스크에 스트리밍하는 것이 더 좋은 방법입니다. 이제 메모리는 대부분의 컴퓨터가 처리할 수 있는 1 MB, 즉 원본 데이터 500 KB와 복사본용 500 KB로 줄게 됩니다.
이를 통해 얻게되는 추가적인 이점은 LabVIEW가 대큐모의 메모리 블록을 할당하는데 소비하게 될 상당량의 시간을 절약할 수 있다는 것입니다. 최신형 컴퓨터에서 250 MB의 데이터를 스트리밍하는데 15 초 내외의 시간이 걸립니다. LabVIEW가 1 GB RAM을 할당하는데에만 해도 그 정도의 시간이 필요할 것입니다.
RAID(Redundant Array of Independent Disks)에 대규모 데이터 세트를 스트리밍하거나 데이터를 저장하려는 경우, 버퍼링 없이 데이터를 전송하여 데이터 복사를 줄이고 데이터 전송 속도를 높일 수 있습니다. 버퍼링을 비활성화하려면, [파일 열기/생성/대체] 함수의 버퍼링 비활성화 입력에 참 값을 연결합니다.
큰 데이터 세트 디스플레이하기
많은 대화식 어플리케이션에서는 다른 사람에가 데이터를 디스플레이하는 것이 가장 중요한 작업입니다. 5백만 개의 데이터 포인트를 디스플레이해야 하는 경우도 있지만, 이는 대부분의 디스플레이에서는 지원할 수 없을 정도의 데이터 크기입니다. 평균적으로 LabVIEW 그래프는 폭이 대략 300에서 1000 픽셀입니다. 5백만 포인트는 실제 웨이브폼 그래프에서 볼 수 있는 크기의 3 배가 넘습니다. 이때 데이터 부분제거(Data decimation)를 통해 문제를 해결할 수 있습니다.
예를 들어, 그래프 상에서 정밀한 픽셀로 대규모 데이터 세트를 나타내고자 한다고 가정해봅니다. 5백만 포인트 버퍼에서 결함이 하나 있는 경우, 플롯은 폭이 1 픽셀인 스파이크 하나가 있는 수평선을 나타날 것입니다. 데이터가 사인파이고 스크린의 픽셀 폭보다 더 큰 주기를 갖고 있는 경우, 그래프는 앨리어스가 없는 상태에서 스크린 전체에 깔끔한 곡선형으로 표시될 것입니다. 최대-최소 부분제거 알고리즘이 이 두 경우에 적용될 수 있습니다.
최대-최소 부분제거는 각 부분제거 간격의 최대 및 최소 데이터 포인트를 사용하는 부분제거입니다. 단순한 부분제거는 부분제거 간격의 데이터 포인트로 각 부분제거 간격의 첫 포인트를 사용합니다. 단순한 부분제거를 사용하면 대상을 작위적으로 앨리어스하게 되므로, 시간이 중요하고 정확도는 중요하지 않는 경우가 아니라면 사용하지 말아야 합니다.
최대-최소 부분제거를 적용하려면, 먼저 그래프의 픽셀 폭을 알아야 합니다. 그래프의 플롯 영역:크기:폭 프로퍼티에서 이를 찾을 수 있습니다. 작위적인 결과과 나오지 않도록, 하나의 픽섹 폭당 최소한 2 개의 부분제거 구간이 필요합니다. 따라서 그래프 픽셀 폭을 2로 곱하여, 데이터를 나눌 구간의 개수를 구합니다. 데이터 길이를 이 숫자로 나눈 후, 올림하여 가장 가까운 정수를 구합니다. 이는 부분제거의 그룹 크기입니다. 각 그룹에서 최대 및 최소 포인트를 찾고, 이를 데이터 세트에서 발생한 순서대로 정렬합니다. 마지막 그룹이 갖고 있는 포인트의 개수가 나머지 그룹보다 적더라도 문제가 되지 않습니다. 그룹이 1 픽셀 폭보다 작은 경우에는 컴퓨터 스크린에서 볼 수 없기 때문에 문제가 될 수는 있습니다. 모든 최대 및 최소 데이터를 연결하여 플롯합니다. 스크린 상에서 한 픽셀 폭당 4 개의 포인트가 있을 것입니다. 이 덕분에, 옆에 있는 다른 픽셀과 겹쳐지지 않고 스파이크가 한 픽셀 폭에서 표시될 수 있습니다. 최대-최소 부분제거를 통해 항상 데이터의 피크를 볼 수 있고, 고주파수의 사인파가 만드는 곡선이 바르게 표시될 수 있습니다. 그래프에 플롯하는 데이터 숫자는 더 적은 상태에서 더 빠른 속도로 이 작업이 모두 수행될 수 있습니다.
다음 그림에서 왼쪽의 데이터를 최대-최소 부분 제거를 사용하여 처리하면, LabVIEW가 오른쪽에 그래프를 생성합니다.
큰 데이터 세트 저장하기
큐나 데이터 값 참조를 사용하여 많은 메모리를 사용하지 않고 큰 데이터 세트를 메모리에 저장합니다. 데이터를 포함하는 단일 원소로 큐를 생성합니다. 데이터를 사용하고 싶을 때마다, 원소를 큐에서 제거합니다. 이는 프로그램의 다른 부분이 동시에 접근할 수 없도록 합니다. 데이터에서 작업하려면, 다시 원소로 큐를 생성합니다. 이때 오직 큐 참조만 전달하면 됩니다. LabVIEW는 큐를 전달할 때에는 필요한 데이터만을 복사합니다. 큐에 이름을 붙이면, 큐 얻기 함수에서 이름을 지정함으로써 언제든지 큐에 대한 참조를 얻을 수 있습니다. 여러 데이터 객체를 생성하는 것은 여러 큐를 생성하는 것 만큼 쉽습니다.
데이터 값 참조를 사용하여 여분의 데이터 복사본을 생성하지 않고 데이터를 저장할 수 있습니다. 데이터 값 참조는 큐보다는 효율성이지만, 타임아웃 옵션은 없습니다. 데이터를 큐에 전달하지 않고, 데이터에 대한 참조를 생성하여 참조를 전달할 수 있습니다. 데이터에서 작업하려면, In Place 원소 구조를 사용합니다. 데이터 값 참조 원소 읽기 / 쓰기 경계 노드는 데이터 값 참조를 입력으로 받고, 사용자가 In Place 원소 구조 안에 있는 데이터에서 작업할 수 있도록 하며, 원래 메모리 공간에 있는 데이터를 대체합니다.
또한 기능적인 글로벌 변수를 사용하여 큰 데이터 세트를 메모리에 저장할 수 있습니다. 기능적인 글로벌 변수를 사용하면, LabVIEW는 데이터를 그룹으로 저장하고 사용함으로써 메모리를 많이 소모하지 않으면서 데이터를 전달할 수 있습니다. 초기화되지 않은 데이터를 지니고 있을 도구로 시프트 레지스터를 사용합니다. 배열 함수를 사용하여 데이터를 읽고, 쓰고, 크기 조정합니다. 배열 함수는 in-place로 작동하며, 데이터 복사본을 생성하지 않습니다. 이 접근법은 일반적으로 큐 접근법보다 더 느립니다.