[Q] 임베디드 멀티 스레드 프로그래밍을 하는데 응답시간이 너무 느려요
제가 실시간 시스템으로, 물체를 인식하면 인식된 물체의 중앙으로 카메라 고개가 옮겨가는 것을 만들고 있고요.
현재 logitech quickcam sphere를 가지고 작업하는데, 이녀석은 pan/tilt(고개가 가로로 회전 혹은 세로로 회전)이 가능한 녀석입니다
pan/tilt 기능 및 이미지 그랩은 V4L2로 구현했습니다.
A] 처음엔 그냥 쌩으로, pan/tilt 해주는 함수를 포직스 쓰레드로 구현해 매 프레임마다 (1초에 10프레임) 쓰레드를 가동시켰습니다.
(이미지 그랩하는 소스는 V4L2 example 소스에서 잡다한 코드를 뺀 녀석입니다.)
이게 인텔 호스트 PC에서는 쌩쌩 잘돌아가는데, 막상 보드에 올리니(PXA270) 죽어버리네요.
(물론 상기 쓰레드 방식으로 구현된 pan/tilt 기능만 수행하는 데모 프로그램은 양쪽서 다 잘 돌아가는데 말이죠.)
B] 따라서, 이 문제가 램 용량 부족인거 같았습니다.
가동되는 스레드는 걍 쌩으로 v4l2 관련 구조체를 설정하고 값 바꾸고 이걸 I/O 출력하는 좀 큰 함수지요.
그래서 요 무거운 기능을 수행하는 스레드를 계속 가동시킬 것이 아니라, 큐 하나를 만들었습니다.
즉, 기존의 pan/tilt스레드는 이동 값만을 요 큐에 집어넣는 기능만 수행하죠.
거기다 단일 메인 스레드를 만들어서, 이 스레드가 큐를 계속 지켜보면서 큐가 비어있지 않으면 빌때까지 pan/tilt 값을 읽어와 장치에 명령을 내리는 것이지요.
.
.
.
-_- 근데 이게 응답시간이 앞서 계속 쓰레드 올리는 것보다 느립니다. 너무 느리다 보니, 한 5초전의 값을 토대로 현재의 고개를 돌려
이게 그냥 정신나간 눈깔일 뿐입니다 ㅠ
흑흑ㅠㅠ
제가 질문드리고 싶은 것은 이렇게 요약할 수 있겠네요
* 임베디드 멀티스레드/V4L2 프로그래밍을 하는데 응답시간을 빠르게 할 수 있는 방법이 있는지요?
A] 호스트 PC에선 돌아가고 보드상에서 안돌아가는 이유가 용량 문제라는 판단이 맞는것인지요?
No) 아니라면, 다른 원인은 무엇이 있을까요?ㅠ
B] 응답시간을 향상시키는 방식을 찾아보았는데요, DMA를 사용하는 방식이 있더군요..
현재 PXA270을 사용하니까 DMA는 달려있는데.... 이게 하드웨어레벨에서 해주는 것인지, 프로그래머가 해줄 수 있는건지
개념이 아예 없습니다.
C] 또, 제가 리눅스 디바이스 드라이버에 대한 개념도 없긴하지만 어줍잖게 들어본것은 IO 장치의 속도/성능 향상을 위해
디바이스 드라이버를 개선 혹은 작성하는 방법이 있다고 들었습니다. 이게 제 경우에서도 가능한 것인지요?
조언을 좀 드리자면
먼저 간략하게라도 디자인을 해보시고 접근하시는 게 좋겠네요.
타켓 보드 탑재 메모리 용량과 개발하신 응용 프로그램 메모리 소모량을 분석하셔야 할 것 같고요.
그리고 대부분의 경우 DMA와 같은 것은 속도 향상에 지대한 영향은 못 줍니다.
속도 향상은 대부분 쓰레드 관련 설계 최적화에서 얻어 집니다.
~~
오 감사합니다
시간도 없는데 삽질할 뻔했군요 :) 감사합니다!
-- 가동되는 스레드는
-- 가동되는 스레드는 걍 쌩으로 v4l2 관련 구조체를 설정하고 값 바꾸고
-- 이걸 I/O 출력하는 좀 큰 함수지요.
-- 그래서 요 무거운 기능을 수행하는 스레드를 계속 가동시킬 것이 아니라, 큐 하나를 만들었습니다.
-- 즉, 기존의 pan/tilt스레드는 이동 값만을 요 큐에 집어넣는 기능만 수행하죠.
-- 거기다 단일 메인 스레드를 만들어서, 이 스레드가 큐를 계속 지켜보면서 큐가 비어있지 않으면
-- 빌때까지 pan/tilt 값을 읽어와 장치에 명령을 내리는 것이지요.
이렇게 바꾸니까 보드에서도 잘 돌아가나요. 그래서 응답시간만 문제가 되든가요?
넹;;
네;; 보드에서는 잘 돌아갑니다....
레이싱 컨디션 문제일지도
쓰레드가 도는 환경이 워낙 차이날테니까요.
pan/tilt 쓰레드가 뭔가 일을 할 동안에 재진입을 하게 될 가능성이 없는지요?
아마도 얘는 재진입을 처리하기가 곤란하지 않을까 싶은데요.
결국 쓰레드로 만들어도 두 쓰레드 간에 메시지 큐가 필요할 것 같은데요.
그리고 포직스 쓰레드에서 일정 시간마다 쓰레드를 돌린다는건 불가능합니다.
스케줄링에 직접 개입할 방법은 없습니다.
헉
헉;;;; 조언 감사드립니다;;;;;;;;;;;;;;;;;;;;;;;;;;
Q
5초전의 방향으로 움직인다는 말을 듣고 생각난건데 큐의 크기가 얼마나 되나요?
지나간걸 오래 가지고 있을 필요는 없잖아요.
또 지나간 경로대로 쫒아가야 할 필요도 없구요.
즉 중앙 위치가 바뀌어서 큐에 새 좌표를 넣을때 큐를 모두 지우고 넣으면 빨라질거같습니다.
또한 그때 이미 이전 위치로 이동하고 있었다면 그 이동을 끝까지 가기 전에 취소하고 갈수있는
구조는 맞는거죠?
여기선 큐가 보존을 하기 위한게 아니라 단지 전달만 하면 되니까 이렇게 해보세요
아니면 아예 큐를 사용하지말고 그냥 x, y 변수만 사용하시던지요.
값이 변하면 이동한다..식으로요.
왠지..
왠지 님께서 말씀하신 바와 같이 해야할 필요성을 절실히 느낍니다. ㅠ
큐를 지우는 것보단 말씀하신 것처럼 그냥 x,y 변수만 사용해야겠어요.. 대신 pan/tilt 호출 간격을 더 늘여야겠지요 ^^;
그리고 다른 곳에서도 조언을 구하다 알게되었는데,
제가 가지고 있는 퀵캠의 FPS을 높여주는 방법이 있었습니다 ^^;
퀵캠을 처음 킬때 노출 자동 조정기능이 켜져 있는데, 이것때문에 실제 FPS가 설정한 값의 반으로 떨어져버리더라고요...
사실 높인다기 보단 원래의 제 성능을 발휘하게 하는것이지만, 이렇게 하니 성능이 좋아졌습니다.
추가적인 최적화는 윗분들의 조언 모두 종합해서 하면 될듯 싶습니다. 조언 주신 분들 정말 감사드립니다! 새해 복 많이 받으세요!! ^^
댓글 달기