2011-04-21 3 views
0

저는 실시간 이미지 조작을 수행하는 Windows 양식 응용 프로그램을 개발하고 있습니다. 사용자 인터페이스는 핵심 요소이며 다중 스레드를 사용하여 UI 스레드와 별도로 이미지 처리 작업을 수행하려고합니다. 뿐만 아니라 계산의 intesity 때문에 여러 스레드에서 이미지 처리를 수행하고자합니다.Windows Forms 응용 프로그램에 다른 스레딩 접근 방식을 결합

이 작업을 수행하는 한 가지 방법은 ThreadStart 대리자를 사용하여 여러 스레드에서 처리하는 것입니다. 이것은 꽤 잘 작동하지만 각 스레드를 명시 적으로 생성하고 있습니다. 내가 살펴본 또 다른 접근법은 OpenMP를 사용하여 여러 스레드에서 처리 작업을 수행하는 것입니다. OpenMP는 사용 가능한 모든 스레드에 자동으로 처리를 할당하므로 훨씬 간단한 방법 인 것 같습니다. 이것은 프로그램이 각각 다른 수의 코어가있는 서로 다른 컴퓨터에서 실행되는 경우 매우 유용합니다. 그러나 나는 사용자 반응성이 openMP 접근법에 부족하다는 것을 알았고, 이것이 결과적으로 UI 스레드에서도 계산이 이루어 졌기 때문에 결론에 도달했습니다.

나는 두 가지 접근법을 결합하려고했는데, 나는 for 루프를 병렬 처리하기 위해 openMP를 사용하여 이미지 처리를 수행하는 함수를 호출하는 threadstart를 사용하여 새 스레드를 시작합니다. 그러나이 작업을 수행 할 때 프로그램에서 사용할 수있는 스레드를 모두 사용하지는 않습니다 (8 개 중 2 ~ 3 개만 사용하는 것 같습니다).

내 질문은 다음과 같습니다.이 두 가지 방법으로 멀티 스레딩을 시도해 보는 것이 좋지 않습니까? 사용 가능한 모든 스레드에서 이미지 처리를 수행하지만 사용자 입력을 처리하기 위해 UI 스레드를 남겨 두는 접근 방식의 조합을 성공적으로 구현하는 방법이 있습니까? 또는 위의 방법 중 하나만 사용하면 더 간단한 구현이 가능합니까? 아마도 threadstart를 사용하여 스레드를 동적으로 만들 수 있다는 것을 알았지 만, 대신 OpenMP를 사용할 수 있다면 좀 더 복잡한 접근 방법처럼 보입니다.

#define CHUNKSIZE 1 
#pragma omp parallel 
{ 
    #pragma omp for schedule(dynamic, CHUNKSIZE) 
    for (i=0;i<numberofrows;i++) 
    { 
     //Process all of the pixels in the given row putting results in the processed data array. 
    }; 
}; 
:

//this sets up a new thread when called for in the form 
public: static void ThreadProc() 
{ 
    ProcessedData=compute(ImageData); //this is the image processing, there are other variable as well as ImageData 
}; 

//this computes the processed image when the user moves a label/node 
private: void labelnode_MouseMove(Object^ /*sender*/, System::Windows::Forms::MouseEventArgs^ e) { 
    //if not being moved or left mouse button not used, exit  
    if (!bMoving || e->Button != System::Windows::Forms::MouseButtons::Left)  
    {  
     return; 
    }; 
    Thread^ oThread = gcnew Thread(gcnew ThreadStart(&Form1::ThreadProc)); 
    oThread->Start(); //launch new thread to do calculations for image processing 
}; 

컴퓨팅 기능은 다음 병렬 루프가 포함되어 있습니다 (: ProcessedData 및 imageData의 픽셀 데이터의 부호없는 문자의 배열 인 주) 여기

는 내가하고 싶은 것을 보여주는 일부 의사입니다

업데이트 : 실제로 디버깅 도구가 응용 프로그램의 전체 성능을 방해하고 있음이 밝혀졌습니다. exe를 외부에서 실행하면 정상적으로 작동합니다. 그러나, 지금은 프로세스가 충분한 시간을 반복 후 충돌이 발생 메모리 누수가 있습니다. OpenMP와 병렬 처리하기 전에 메모리 누수가 없었을 것입니다. 따라서 스레드의 지속적인 열기 및 닫기에서 남아있는 메모리가 남아 있는지 궁금합니다. 어떤 아이디어?

답변

0

당신의 접근 방식은 맞습니다. UI 응답 성을 위해 메인 스레드를 유지하고 OpenMP (또는 다른 병렬 프레임 워크)를 사용하여 연산 집약적 인 작업을위한 별도의 스레드를 시작하여 병렬로이 작업을 처리하는 것이 좋습니다.

이 방법으로 모든 HW 스레드/코어를 사용하지 않는 이유는 별도의 질문입니다. 로드 불균형 또는 일부 동기화 문제 또는 중요한 일련의 계산 또는 모든 스레드에 대해 항상 부족한 작업량으로 인한 것일 수 있습니다.

+0

응답 해 주셔서 감사합니다. OpenMP 루프는 처리 할 이미지의 픽셀 행을 동적으로 보내도록 설정됩니다. 그것은 완벽하게 threadstart없이 모든 8 개의 사용 가능한 스레드를 사용하므로 부하 불균형이나 동기화 문제 등 생각하지 않지만 내가 스레드 시도를 사용하려고 할 때 parrallelised에 대한 UI 스레드에서 스레드를 분리하는 것만 스레드에서 실행하는 것 . num_threads를 수동으로 설정하려고 시도했지만 차이가없는 것 같습니다. – nemepi

+0

메인 스레드가 수행하고있는 작업과 계산 스레드가 수행하는 작업에 대한 (의사) 코드와 OpenMP 사용 방법이 도움이 될 것입니다. –

+0

질문의 편집에 몇 가지 코드를 추가했습니다. – nemepi

관련 문제