티스토리 뷰


LabVIEW를 이용하여 Vision 어플리케이션 개발시에 생산자-소비자 패턴을 적용하게 되면 소비자 패턴에서 원활히 데이터를 처리하지 못하여, 생산자와 소비자 간의 루프 동기화가 이루어지지 않게 됩니다. 


이러한 문제가 발생하는 이유는 무엇일까요? 

이 문제의 원인은 IMAQ 함수 처리 방식 때문입니다. IMAQ 함수에서 사용하는 Image Out 값은 실질적인 이미지의 Byte 값이 들어가 있는 배열 형태가 아니라, 이미지 값을 저장하고 있는 배열의 메모리 위치를 나타냅니다. 


따라서 Queue 함수에 전달을 할때 IMAQ 함수에서 생성된 Image Out 값을 넣게 되면 메모리의 위치만을 알려주는 메모리 주소를 전달하게 됨으로써 처리가 원할하지 않게 되는 것입니다. 


좀 더 유식하게 이야기 하면 IMAQ 함수를 통해서 생성된 Return 값은 Value가 아닌 Reference이기 때문에 발생하는 문제입니다. Call by Value와 Call by Reference를 공부하시면 어떠한 차이가 있는지 명확하게 알 수 있습니다. ^^;;


즉 생산자 / 소비자 아키텍처를 사용하는 응용 프로그램에서 생산자와 소비자 사이에서 영상 데이터를 전달 할 때 생산자에서 전달하는 메모리 값에 이미지 데이터가 겹쳐지게 되고, 이로인해 소비자 루프에서 처리되는 이미지가 변경되거나 덮어쓰기 과정이 발생을 하게 되어 추가적인 프로세스 시간이 필요하게 되는 것입니다. 


이러한 문제를 해결하는 방법은 2개의 루프 실행에 앞서 다수개의 Image Out(배열)을 생성하여 Ring 형태로 처리를 함으로써 덮어쓰기 및 지연에 대한 문제를 해결할 수 있습니다. 


Ring 처리 방식은 Computer Science 학부에서 알고리즘을 배울 때 나오는 내용입니다. 데이터 경합 및 데이터 전달에 문제가 발생을 할 때 여러개의 노드를 생성하여 이 노드들의 처리를 순차적으로 진행하면서 노드의 갯수 만큼 처리가 되면 첫번째 노드로 데이터 전달을 돌려서 처리하게 됩니다. 이렇게 하면 유한적인 메모리 사용을 통해 데이터 경합에 대한 문제를 사용자가 원하는 수준만큼 프로그램을 돌리면서 해결할 수 있습니다. 


다수의 이미지 버퍼를 생성하여 알고리즘상에서 이 배열의 index를 변경시켜 이미지 수집시에 다른 메모리 영역에 데이터를 넣고 이를 소비자에 전달함으로써 성능 및 문제점을 해결 시킬 수 있는 것입니다. 


이 부분을 LabVIEW로 구현을 하면 아래와 같습니다. 


먼저 생산자 부분입니다. 아래의 주석처럼 사용자가 원하는 갯수만큼 IMAQ 함수를 통해서 Image Out의 갯수를 만듭니다. 그리고 생산자 루프에서 몫과 나머지를 이용하여 매번 다른 배열의 Index에 대한 메모리 부분을 이용하여 이미지를 전달합니다. 


 


소비자 부분은 전달받은 이미지 주소를 통해서 처리를 하면 되기 때문에 별다른 프로세스가 필요하지 않습니다. 


 


마지막으로 프로그램이 종료가 되면 기존에 생성했던 Image Out 배열에 대한 부분을 해제하여 메모리에 할당된 부분을 해제합니다. 


 


이 글에서는 비전을 생산자-소비자로 처리시에 문제가 되는 데이터 경합에 대한 해결 방안을 알아보았습니다. 




댓글