자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
Delphi TParallel.For 코어 사용 이게 맞나요?
2019.09.30 23:40
본 게시판은 개발자들이 자유롭게 질문과 답변을 공유하는 게시판입니다.
* 따라서 최대한 정중하게 질문을 올려 주세요.
* 질문을 상세히 작성해 주실 수록 좋은 답변이 올라 옵니다.
* 다른 분들도 참고할 수 있도록 결과 댓글 필수(또는 감사 댓글)
(결과 댓글을 달지 않는 경우 다음 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)
-----------------------------------------------------------------------------------------------
안녕하세요~~
델파이에서 TParallel.For 문으로 스레드를 사용하고자 합니다.
종료하기전까지 무한 루프를 돌리는데 20개를 계속 무한루프 돌립니다.
OpenCV로 20개의 영상을 종료전까지 무한루프 돌리는는게 목표입니다.
procedure TFormMain.btnPlayClick(Sender: TObject);
begin
// 스레드풀
if FPool = nil then
begin
FPool := TThreadPool.Create;
FPool.SetMaxWorkerThreads(4); // 이 값을 4, (2CPU X 25), 400, 800등 수정하여 테스트 해 봄.
FPool.SetMinWorkerThreads(4);
end;
b_Result := True;
This_capture := cvCreateFileCapture(PAnsiChar(s_Url)); // rtsp 주소로 영상 캡처
Src_Img := cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); // 테스트이므로 640 x 480영상 1개로 20개 재생하려고
if Assigned(This_capture) then
begin
TTask.Run(procedure
begin
while b_Result do // 영상 한프레임을 받아 TImage 20개에 뿌리는 것을 계속 루프돌리여고.(무식한 방법?)
begin
Src_Img := cvQueryFrame(This_capture); // 한프레임 받아온다.
TParallel.For(4, 1, 20, Proc_Display); // 1~20까지 병렬 스레드 하면서 아래 Proc_xx 수행
end;
end, FPool);
end;
end;
procedure TFormMain.Proc_Display(index : integer);
begin
TThread.Synchronize(TThread.CurrentThread,
procedure
begin
// Src_Img를 TImage에 뿌려줌.
IPLImageToFMXBitmap(Src_Img, TImage(FormMain.FindComponent('Disp'+IntToStr(index))).Bitmap, False);
end);
end;
시스템은,
Intel Xeon 4114 2.20GHz, 2.19GHz (2개) 20Core x 2 = 40 Core
네트웍 : 1기가랜(프로그램과 서버는 로컬망)
실행하면, 외견상 정상적으로 잘 됩니다.
최대 몇개의 영상을 재생할 수 있는지 확인하기 위해 프로그램을 여러번 실행해보았습니다.
그리고 코어를 최대한 활용하는지....
작업관리자를 보면 9개의 프로그램을 실행(총 180개 영상 재생중)인데 CPU와 메모리, 네트웍 넉넉합니다.
그런데 CPU의 총 40개의 노드를 보면 두번째 CPU의 노드들은 아래와 같이 이렇게 쉬는 애들이 너무 많습니다.
아직 자원이 많이 남아있다고 생각이 들었는데 뭔가 이상한 것이...
아래와 같이 화면에 재생되는 영상에는 타이머가 있습니다.
자세히 보니 1초단위가 아니라 점점 느려지고 있었습니다.
프로그램1~6개정도는 시간의 딜레이(프레임의 딜레이)를 느끼지 못했는데 그 이상 프로그램을 실행하니
타이머가 조금씩 밀리기 시작합니다.
그런데 왜 시스템의 자원은 남아 도는건지 모르겠습니다.
넘쳐나는 코어를 팍팍 써줬으면 좋겠는데 왜 두번째 CPU의 대부분의 코어들이 놀고 있는지....
FPool.SetMaxWorkerThreads(4); 이 값을 여러번 수정하여 테스트 해보아도 변함이 없습니다.
영상의 사이즈를 640 x 480 에서 320으로 줄이면 프로그램 인스턴스 9개까지 잘 수행되는것 같습니다.
단지, 각 단위 영상의 사이즈를 줄여서 프레임 딜레이 없이 더 많은 프로그램 인스턴스를 수행할 수 있다는건 이해가 가지만
자원을 더 쓰면 프레임 딜레이가 없을텐데 왜 코어를 모두 활용하지 못하는지 잘 모르겠습니다.
이런 스펙에서 굳이 스레드를 이렇게까지 구현할 필요 있겠나 싶어서 처음엔
Application.OnIdle 안에서 For 문으로 무식하게 돌렸었는데 1~20개 영상 순차적으로 돌려도 스펙이 워낙 좋아서
잘 돌아갔던 기억이 있는데 똑같이 영상의 싱행수가 많아지면 멈추진 않는데 영상의 재생수에 비례하면서 슬슬 프레임이 느려지는 현상이 완전히 동일합니다.
하나의 프로그램에서 20개가 아니라 64개의 영상을 재생해 보았지만 영상의 전체 64개의 영상이 모두 프레임이 살짝 느려졌었습니다.
물론 자원은 여전히 남아돌고 있었구요.
또 TParellel.For를 사용하지 않고 고전적인 델파이 스레드를 사용해 보기도 했었습니다.
영상이 20개이니까 TThread.Create를 20회하고 TThread.Execute에서 코드를 작성하여 충돌없이 잘 되었으나
똑같은 영상 20개 재생하는데 메모리 누수없이 처음부터 메모리 사용량이 어마어마합니다 ㅠ.ㅠ
이 경우는 코어를 고르게 사용하는 것 같습니다.
제가 어떤 부분을 놓치고 있을까요?
댓글 2
-
험프리
2019.10.02 15:14
-
아크나톤
2019.10.11 14:53
threadpool과 함께 TParallel.For 테스트 그리고 채널 수만큼 TThread 배열을 생성하여 시도를 해보고 있는데
여전히 TParallel.For는 코어를 모두 사용하지 않는것으로 보입니다.
구글링을 해보니 threadpool 과 TParallel.For에서 저와 같은 문제에 대해 언급한 자료가 있어 일단 포기했습니다 ㅠ.ㅠ
일단 전통적인 델파이 TThread를 이용하여 주어진 스펙에서 최대 재생 한계를 테스트하여 다시한번 결과를 올리도록 하겠습니다.
감사합니다.
Delphi TParallel.For 코어 사용 이게 맞나요?
2019.09.30 23:40
본 게시판은 개발자들이 자유롭게 질문과 답변을 공유하는 게시판입니다.
* 따라서 최대한 정중하게 질문을 올려 주세요.
* 질문을 상세히 작성해 주실 수록 좋은 답변이 올라 옵니다.
* 다른 분들도 참고할 수 있도록 결과 댓글 필수(또는 감사 댓글)
(결과 댓글을 달지 않는 경우 다음 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)
-----------------------------------------------------------------------------------------------
안녕하세요~~
델파이에서 TParallel.For 문으로 스레드를 사용하고자 합니다.
종료하기전까지 무한 루프를 돌리는데 20개를 계속 무한루프 돌립니다.
OpenCV로 20개의 영상을 종료전까지 무한루프 돌리는는게 목표입니다.
procedure TFormMain.btnPlayClick(Sender: TObject);
begin
// 스레드풀
if FPool = nil then
begin
FPool := TThreadPool.Create;
FPool.SetMaxWorkerThreads(4); // 이 값을 4, (2CPU X 25), 400, 800등 수정하여 테스트 해 봄.
FPool.SetMinWorkerThreads(4);
end;
b_Result := True;
This_capture := cvCreateFileCapture(PAnsiChar(s_Url)); // rtsp 주소로 영상 캡처
Src_Img := cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); // 테스트이므로 640 x 480영상 1개로 20개 재생하려고
if Assigned(This_capture) then
begin
TTask.Run(procedure
begin
while b_Result do // 영상 한프레임을 받아 TImage 20개에 뿌리는 것을 계속 루프돌리여고.(무식한 방법?)
begin
Src_Img := cvQueryFrame(This_capture); // 한프레임 받아온다.
TParallel.For(4, 1, 20, Proc_Display); // 1~20까지 병렬 스레드 하면서 아래 Proc_xx 수행
end;
end, FPool);
end;
end;
procedure TFormMain.Proc_Display(index : integer);
begin
TThread.Synchronize(TThread.CurrentThread,
procedure
begin
// Src_Img를 TImage에 뿌려줌.
IPLImageToFMXBitmap(Src_Img, TImage(FormMain.FindComponent('Disp'+IntToStr(index))).Bitmap, False);
end);
end;
시스템은,
Intel Xeon 4114 2.20GHz, 2.19GHz (2개) 20Core x 2 = 40 Core
네트웍 : 1기가랜(프로그램과 서버는 로컬망)
실행하면, 외견상 정상적으로 잘 됩니다.
최대 몇개의 영상을 재생할 수 있는지 확인하기 위해 프로그램을 여러번 실행해보았습니다.
그리고 코어를 최대한 활용하는지....
작업관리자를 보면 9개의 프로그램을 실행(총 180개 영상 재생중)인데 CPU와 메모리, 네트웍 넉넉합니다.
그런데 CPU의 총 40개의 노드를 보면 두번째 CPU의 노드들은 아래와 같이 이렇게 쉬는 애들이 너무 많습니다.
아직 자원이 많이 남아있다고 생각이 들었는데 뭔가 이상한 것이...
아래와 같이 화면에 재생되는 영상에는 타이머가 있습니다.
자세히 보니 1초단위가 아니라 점점 느려지고 있었습니다.
프로그램1~6개정도는 시간의 딜레이(프레임의 딜레이)를 느끼지 못했는데 그 이상 프로그램을 실행하니
타이머가 조금씩 밀리기 시작합니다.
그런데 왜 시스템의 자원은 남아 도는건지 모르겠습니다.
넘쳐나는 코어를 팍팍 써줬으면 좋겠는데 왜 두번째 CPU의 대부분의 코어들이 놀고 있는지....
FPool.SetMaxWorkerThreads(4); 이 값을 여러번 수정하여 테스트 해보아도 변함이 없습니다.
영상의 사이즈를 640 x 480 에서 320으로 줄이면 프로그램 인스턴스 9개까지 잘 수행되는것 같습니다.
단지, 각 단위 영상의 사이즈를 줄여서 프레임 딜레이 없이 더 많은 프로그램 인스턴스를 수행할 수 있다는건 이해가 가지만
자원을 더 쓰면 프레임 딜레이가 없을텐데 왜 코어를 모두 활용하지 못하는지 잘 모르겠습니다.
이런 스펙에서 굳이 스레드를 이렇게까지 구현할 필요 있겠나 싶어서 처음엔
Application.OnIdle 안에서 For 문으로 무식하게 돌렸었는데 1~20개 영상 순차적으로 돌려도 스펙이 워낙 좋아서
잘 돌아갔던 기억이 있는데 똑같이 영상의 싱행수가 많아지면 멈추진 않는데 영상의 재생수에 비례하면서 슬슬 프레임이 느려지는 현상이 완전히 동일합니다.
하나의 프로그램에서 20개가 아니라 64개의 영상을 재생해 보았지만 영상의 전체 64개의 영상이 모두 프레임이 살짝 느려졌었습니다.
물론 자원은 여전히 남아돌고 있었구요.
또 TParellel.For를 사용하지 않고 고전적인 델파이 스레드를 사용해 보기도 했었습니다.
영상이 20개이니까 TThread.Create를 20회하고 TThread.Execute에서 코드를 작성하여 충돌없이 잘 되었으나
똑같은 영상 20개 재생하는데 메모리 누수없이 처음부터 메모리 사용량이 어마어마합니다 ㅠ.ㅠ
이 경우는 코어를 고르게 사용하는 것 같습니다.
제가 어떤 부분을 놓치고 있을까요?
댓글 2
-
험프리
2019.10.02 15:14
-
아크나톤
2019.10.11 14:53
threadpool과 함께 TParallel.For 테스트 그리고 채널 수만큼 TThread 배열을 생성하여 시도를 해보고 있는데
여전히 TParallel.For는 코어를 모두 사용하지 않는것으로 보입니다.
구글링을 해보니 threadpool 과 TParallel.For에서 저와 같은 문제에 대해 언급한 자료가 있어 일단 포기했습니다 ㅠ.ㅠ
일단 전통적인 델파이 TThread를 이용하여 주어진 스펙에서 최대 재생 한계를 테스트하여 다시한번 결과를 올리도록 하겠습니다.
감사합니다.
다음 링크의 내용과 샘플을 참고해 올바르게 구현된것인지 검토해 보시기 바랍니다.
병렬(패러럴) 컴퓨팅 라이브러리 소개 - https://blog.hjf.pe.kr/247
Using the Parallel Programming Library - http://docwiki.embarcadero.com/RADStudio/Rio/en/Using_the_Parallel_Programming_Library
——————
답글이 도움이 되셨는지 다른 분들도 참고할 수 있도록 결과 댓글 부탁드립니다.
(결과 댓글이 없는 경우 다른 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)