티스토리 뷰



[LabVIEW] In Place Element Structure에 대해서 - 랩뷰 메모리 관리 방안


LabVIEW는 Text-Based 언어와는 달리 메모리를 Compiler에서 알아서 처리를 해줍니다. 이는 개발자에게는 효율적인 측면을 부여하지만, 리소스 관리 입장에서는 좋지 않은 퍼포먼스를 보여줄 수 있습니다. 


데이터 흐름 프로그래밍은 일반적으로 변수를 사용하지 않고 입력데이터를 소비하고 데이터를 출력을 생성하여 제공합니다. 이를 그대로 이용하면 많은 양의 메모리를 사용하고, 성능이 느린 어플리케이션이 됩니다. 모든 함수는 출력이 전달되는 모든 대상에 데이터의 복사본을 생성합니다. 랩뷰는 이를 Inplaceness를 통해서 개선시킬 수 있습니다. 


특히 LabVIEW는 특정 데이터(특히 배열) 를 처리할 때 사용되는 연산자의 연산을 위해서 관련 데이터를 메모리에 복사한 뒤 결과를 기존의 데이터에 넣도록 되어 있습니다. 예를 들어, 배열 10개의 데이터에 특정 값을 더하는 연산을 사용하게 되면 배열 10개에 대한 메모리를 추가적으로 복사하여 데이터를 처리하게 됩니다. 


이러한 메모리의 비효율성을 제거하기 위해서 LabVIEW는 In Place 원소 구조를 제공하고 있습니다. 이는 LabVIEW 컴파일러가 특정한 작업을 수행하는 방법을 컨트롤하며 일부 경우에 메모리와 VI 효율성을 향상시킵니다. 


In Place 원소 구조를 사용하여, LabVIEW 컴파일러가 데이터값을 복사하고 메모리에 저장하지 않도록 하면서, 배열, 클러스터, 배리언트, 웨이브폼의 데이터 원소에 대한 연산을 수행합니다. 또한 이 구조를 사용하여 다른 데이터 타입의 연산도 메모리에서 같은 데이터 공간을 유지하면서 수행할 수 있습니다. 구조의 경계에서 마우스 오른쪽 버튼을 클릭한 후 수행하려는 작업과 일치하는 경계 노드를 선택합니다.


In Place 원소 구조에서 지원하는 노드는 아래와 같습니다. 


  • 배열 인덱스 / 원소 대체 경계 노드(Array Index / Replace Elements border node)
  • 배열 분리 / 부분배열 대체 경계 노드(Array Split / Replace Subarrays border node)
  • 원소 풀기 / 묶기 경계 노드(Unbundle / Bundle Elements border node)
  • 웨이브폼 원소 풀기 / 묶기 경계 노드(Waveform Unbundle / Bundle Elements border node)
  • 배리언트를 원소로 / 원소에서 배리언트로 경계 노드(Variant To / From Element border node)
  • In Place 원소 입력 / 출력 경계 노드(In Place In / Out Element border node)
  • 데이터 값 참조 원소 읽기 / 쓰기 경계 노드(Data Value Reference Read / Write Element border node)


참고로 특정 데이터에서 하나의 함수를 이용하여 하나의 출력을 가지는 결과를 받고자 한다면 LabVIEW의 컴파일러에서 자동적으로 In Place 구조를 사용하게끔 합니다. 따라서 단순 데이터 처리시에는 In Place 구조를 사용하지 않으셔도 무방합니다. 


그럼 In Place 원소 구조를 사용하였을 때와 사용하지 않았을 때 vi에서 사용하는 메모리에 대해서 확인을 해보도록 하겠습니다. 


예를 위해서 3개의 문자열로 이루어진 특정 클러스터의 데이터를 대문자로 변경하여 각 다른 3개의 클러스터 인디게이터에 출력하는 예를 만들어보았습니다. 기본적으로 In Place 구조를 사용하지 않고 데이터를 처리하기 위해서는 아래와 같이 구현이 가능하겠죠? 


이를 In Place 구조를 이용해서 구현을 하면 아래와 같이 변경을 할 수 있습니다.


이 두개의 코드가 결과론 적으로 어떻게 메모리를 다르게 쓰는지를 파악하기 위해서는 LabVIEW의 성능과 메모리(Performance and Memory) 를 통해서 확인이 가능한데요. 한글판에서는 도구 - 프로파일 - 성능과 메모리를 누르시면 됩니다. 



성능과 메모리 프로그램을 실행시킨뒤 메모리를 보기위해서 메모리 부분의 체크박스를 설정합니다. 그리고 시작 버튼(Start)을 누른뒤 해당 vi를 실행합니다. vi가 종료되면 성능과 메모리의 정지버튼(stop)을 누릅니다.


정지버튼을 누르게 되면 각 vi에 대한 사용 메모리에 대한 정보를 알 수 있습니다. 아래의 그림은 위 코드에 대한 결과를 보여줍니다.


In Place 원소 구조를 사용하는 방법이 약 0.08k 정도의 바이트를 덜 사용하고 있네요. 위의 코드가 비교적 많이 간단한 코드이기 때문에 메모리가 별 차이가 나지 않아 보이지만, 코드가 복잡하면 복잡할 수록 사용하는 메모리의 양의 차이는 급증할 수도 있습니다. (어떻게 코드를 최적화 하느냐에 따라 달라지겠지요.)



메모리 사용은 결국 랩뷰에서 메모리 할당(Memory Allocation)을 얼마나 많이하는가, 덜 하는가의 차이로 발생을 할 것입니다. 따라서 메모리 관리를 할 때 메모리 할당 부분을 신경써줘야 합니다.


자신이 만든 코드에서 메모리가 어디에서 어떻게 할당되는지를 확인하기 위해서는 도구 - 프로파일 -  버퍼 할당 보이기(Tools - Profile - Show Buffer Allocation)을 누르면 됩니다. 이 메뉴를 누르면 아래와 같은 창이 뜨게 되는데, 코드에서 Refresh 버튼을 누르면 어떠한 부분에서 메모리 할당이 발생하였는지 알 수 있습니다. 



아래의 코드에서 실행을 하면 빨간색으로 표시된 부분이 깜빡깜빡 거립니다. 그 부분이 LabVIEW 상에서 메모리 할당이 발생한 부분을 나타내게 되는것이죠. 아래의 결과를 보더라도 In Place 구조보다 기존의 클러스터 코드에서 많은 메모리 할당이 발생을 한것을 알 수 있습니다. 


이러한 이유로 아래의 코드가 더 많은 메모리를 사용하게 되는것입니다. 

마치면서, 

간단하거나, 대부분의 경우에는 메모리 할당 및 VI 퍼포먼스에 대해 신경을 쓸 필요가 없습니다. 하지만 대용량의 데이터를 처리하거나 32비트 OS에서 큰 어플리케이션을 돌려야 하는 경우라면 메모리에 신경을 써야 합니다. 이러한 경우에 사용할 수 있는 여러가지 방법 중 하나가 In Place 구조입니다. 결론적으로 이 구조를 모든 VI에 무조건 사용하는 것이 아닌, 환경상 필요할 때만 적용하시면 될것 같습니다. 


이 글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.



댓글