설치 파일 만들고, System 폴더의 INI를 바로 접근 하기기위해서 관리자 권한으로 실행 시키자.

1차 Test

대상 : 644*484 Color이미지의 Red와 Green색상 변경.

코드 : CPU용 이중 for문으로 구성, GPU Cuda 병렬 처리 방식으로 구성.

속도 : CPU 3 msec, GPU 11 msec CPU가 빠르다.(debug, release 같은 현상)

       -> Memory 생성 복사가 추가 되었음으로 CPU 쪽에도 추가 ( 속도 변화 없음)

결론 : Data양이 적을때에는 CPU가 3배 이상 빠르다.(GPU로 메모리 복사가 생기지 않음으로)

     - CPU : 적은 Data, 복잡한 연산에 적합.

     - GPU : 다량의 Data, 단순(CPU에 비해) 연산에 적합.

 

2차 Test

대상 : 상동

코드 : 각 처리위치 반복 수행 제일 안쪽에서 같은 동작 1000회 반복.

속도 :  debug Mode : CPU 2438 msec, GPU 2829 msec

         Release Mode: CPU 1180msec, GPU 3 msec(393배 빠름)

 

*cudaDeviceSynchronize();로 GPU 동작 완료 체크.

 

CPU:2438msec, GPU:2829msec
CPU 1180msec, GPU 3msec(393배)

 

추가 : 이미지 크기 9999*7514 크기 Test

   1회교환

        Debug : CPU 930 msec, GPU  : 2598 msec

        Release : CPU 139 msec, GPU : 358 msec

   100회 교환

        Release : CPU 32288 msec, GPU : 378(최초 511) msec

   1000회 교환

        Release : CPU 측정 불가, GPU : 352 msec

 

Test 진행 코드

'작업 > Cuda' 카테고리의 다른 글

NVIDIA Cuda Cores 참고  (0) 2022.02.24
Cuda Block Thread 설정.  (0) 2020.05.26
기존 Project Cuda Link時 오류  (1) 2020.05.06
VS2017 - NVIDIA Cuda 연결  (0) 2019.12.03

1) Cuda 10.2 Download

OS와 현재 설정에 따라 맞게 설정 하여 Download

2) "cuda_10.2.89_441.22_win 10.exe"설치(2.5 GByte)

3) VS2017 설정 (Consol Test Project 생성 후)

지정 빌드 설정

4) Cuda Lib 추가.(Debug & Release : cuda.lib; cudart.lib; cublas.lib; cufft.lib)

링커 Lib 등록

5) Test.cuh, Test.cu 파일 추가.

확장자 *.cuh, *.cu로 설정 된다.

6) 기본 Test 코드 작성

Test용 Add 함수

7) 컴파일 및 실행

'작업 > Cuda' 카테고리의 다른 글

NVIDIA Cuda Cores 참고  (0) 2022.02.24
Cuda Block Thread 설정.  (0) 2020.05.26
기존 Project Cuda Link時 오류  (1) 2020.05.06
CPU-GPU 속도 Test  (0) 2019.12.03

CriticalSection : 하나의 Process에서 여러개의 Thread의 상호배제 구현
    선언 : CRITICAL_SECTION m_CrtSection;
    초기 :
    생성 : InitializeCriticalSectionAndSpinCount(&m_CrtSection, 2000);//Multi CPU를 지원 Spin Count를 추가 한다.
    진입 : EnterCriticalSection(&m_CrtSection);
    진출 : LeaveCriticalSection(&m_CrtSection);
    소멸 : DeleteCriticalSection(&m_CrtSection);

 

Mutex : 이름을 지정하여 여러개의 Process의 Thread에서도 상호배제 가능.Mutex는 동기화 대상이 오직 하나뿐일 때
    선언 : HANDLE m_hMutex;
    초기 : m_hMutex=NULL;
    생성 : m_hMutex=CreateMutex(NULL,FALSE,NULL); //OpenMutex()
    진입 : WaitForSingleObject(m_hMutex,INFINITE);
    진출 : ReleaseMutex(m_hMutex);
    소멸 : if(m_hMutex !=NULL ) CloseHandle(m_hMutex);

 

Semaphore : 여러 Process의 한가지 자원에 접근 배제.Semaphore는 동기화 대상이 하나 이상일 때 사용
    선언 : HANDLE m_hSemaphore;
    초기 : m_hSemaphore=NULL;
    생성 : m_hSemaphore= CreateSemaphore(
            NULL, // default security attributes
            3, // initial count. MAX_COUNT 10
            3, // maximum count. MAX_COUNT 10
            NULL); // unnamed semaphore

            WaitForMultipleObjects(5, &aThread[0], TRUE, INFINITE);
    진입 : dwWaitResult = WaitForSingleObject( 
            m_hSemaphore, // handle to semaphore
            0L); // zero-second time-out interval
            // Return value : 리턴값 ( dwWaitResult 에 저장되는 값 )
            // WAIT_ABANDONED 0x00000080L
            // WAIT_OBJECT_0 0X00000000L
            // WAIT_TIMEOUT 0x00000102L
            // WAIT_FAILED 0xFFFFFFFF(DWORD)
    진출 : ReleaseSemaphore(m_hSemaphore, // handle to semaphore
            1, // increase count by one
            NULL) ) // not interested in previous count

    소멸 : if(m_hSemaphore !=NULL ) CloseHandle(m_hSemaphore);

 

Event
    선언 : HANDLE m_hEvent;
    초기 : m_hEvent=NULL;
    생성 : m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(m_hEvent);
    진입 : WaitForSingleObject(pDlg->m_hEvent, INFINITE);
    진출 : ResetEvent( hHandle );// 원하는 작업을 처리한다.
    소멸 : if(hHandle !=NULL ) CloseHandle(hHandle);
         

    이벤트 발생은 SetEvent(m_hEvent); //return value

        WAIT_FAILED : fail, GetLastError로 원인을 알수가 있다 이경우 logic을 빠져나간다
        WAIT_ABANDONED : 이 경우는 Event Object를 reset 하고 다시 WaitForSingleObject()를 호출한다
        WAIT_OBJECT_0 : 기다리던 Event가 signal 된 경우
        WATI_TIMEOUT : time-out 된 경우

Opencv 3.4 이후 문제점.
(제공 버전과 Source Build를 통해 Test를 진행하였다. 4.1.2, 3.8.4, 3.4.0 )

- Memory Leak이 있다.(단지 링크 순서에 의한 것이라지만-Debug상)

 

OpneCV 진영의 먹칠(??)이다 ㅡ.ㅡ;


조치 1)
Static MFC DLL로 조치
     --> cv::Mat을 사용할 때 __acrt_first_block == header
heap Error 발생.(debug에서만 발생.)
(사용 불가.)
     --> Local Project는 Debug이지만 Dll은 신뢰 하영 Release로 Link시 사용하는 Opencv C++ Class Link error 발생.
(사용 불가.)

조치 2)
모두 동적 Link로 Build 지연된 DLL로 변경. 프로그램 시작(동작 없이) 종료 시 Leak 없음.
     -->cv::Mat Class 함수 호출 IplImage 사용호 종료 시 Memory Leak 발생.

결론 현재 VS2017로 컴파일하는 3.2 버전 이상에서는
     => Memory Leak을 조치하면, __acrt_first_block == header 발생으로 C++Mat를 사용할 수 없다.
     => 다중 스레드 디버그(/MTd and /MT)에서 그나마 유연하게 동작한다.
          (__acrt_first_block == header를 발생시키는 코드도 있다.)
     => 3.2 이상 버전으로 갈수록 C++형태의 코드와 더 많은 STL사용으로 컴파일 강도가 높아지고 있는 듯하다.

 

다른 분들은 어떠실지 모르지만 현재 3.2 버전 이후에는
Memory Leak, Heap에러의 조치가 없다면, 버전업을 할 수 없을 듯하다.
- 가짜 Memory Leak은 Main S/W Debugging을 힘들게 한다.
- Heap에러는 S/W 신뢰도를 떨어뜨린다.

 

다른 의견이나 정보가 있으시면 공유 부탁드립니다.........

 

Heap Error 발생 코드. (3.4.0 이후...)

void MatTest(Mat*pdraw)
{
	Mat ProcImg = pdraw->clone();
	vector<vector<Point>> contours;
	cv::findContours(ProcImg, contours, RetrievalModes::RETR_EXTERNAL, 
    ContourApproximationModes::CHAIN_APPROX_NONE);
}
void CMatTesterDlg::OnBnClicked()
{
	TCHAR szFilter[] = 
    _T("Image (*.bmp, *.gif, *.jpg *.tif)|*.bmp;*.gif;*.jpg;*.tif|All Files(*.*)|*.*||");
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter, GetParent());
	dlg.m_ofn.lpstrInitialDir = MARK_IMG_PATH;
	if (IDOK == dlg.DoModal())
	{
		USES_CONVERSION;
		CString strPathName = dlg.GetPathName();
		Mat matLoadImg = imread(W2A(strPathName.GetBuffer(strPathName.GetLength())), 
        cv::IMREAD_COLOR);

		if (matLoadImg.empty() != true)
		{
			Mat matCh1Img;
			cvtColor(matLoadImg, matCh1Img, ColorConversionCodes::COLOR_RGB2GRAY);
			
			cv::threshold(matCh1Img, matCh1Img, 50, 255, THRESH_BINARY);
			MatTest(&matCh1Img);
			
			namedWindow("Process", WINDOW_NORMAL); // Create a window for display.
			imshow("Process", matLoadImg);
		}
	}
}

 

 

설정 상태.

'작업 > OpenCV' 카테고리의 다른 글

CvvImage 추가 3.4 까지  (0) 2021.11.09
처리시간 측정  (0) 2020.07.17
OpenCV 컴파일(3.4.0, 3.4.8, 4.1.2)  (0) 2019.11.21
OpenCV 4.x.x 사용 C++ Runtime Library Debug  (0) 2019.11.20
OpenCV Memory Leak  (0) 2019.11.20

생성 시 주의 점

 

1) Memory Leak현상.

a) 정적 라이브러리에서 MFC사용

=> 기본 OpneCV가 동적 Link DLL로 컴파일됨으로 C++ 사용 코드에서 오류 발생 시킴 비추천

https://sw-mcreator.tistory.com/15?category=816240

MFC 사용 방식 변경

b) 지연 dll등록으로 처리.(동적 오류, Memory Leak둘다 해결) 추천

DLL, Lib 위치한 폴더 지정
Lib를 종속시키고, DLL은 지연 시키다.

 

컴파일 OpneCV 3.4.0(OpneCV 4.1.2동일)

(CMake를 통한 Visual Studio 프로젝트 만들기.)

 

 

1) source Code 폴더 선택
2) 출력 폴더 선택 (VS2017 64 or 32)
3) button Configure 진행(Visual Studio의 종류와 64/32bit 선택)
4) Option 선택(검색창에서 Option 검색)
- OPENCV_EXTRA_MODULES_PATH <다운로드 폴더 선택.>opencv_contrib-3.4.0/modules
- OPENCV_ENABLE_NONFREE

- BUILD_PERF_TESTS
- BUILD_TESTS
- BUILD_JAVA
- BUILD_PACKAGE
- BUILD_opencv_world

- WITH_1394
- WITH_GSTREAMER
- WITH_LAPACK
- WITH_VTK

- CMAKE_INSTALL_PREFIX <경로 선택>
- INSTALL_C_EXAMPLES

5) button Generate 진행
6) button Open Project 진행
7) Visual Studio Debug/Release 컴파일 진행.
8) 프로젝트중 "INSTALL"프로젝트만 따로 Build 진행.
-> 위에서 선택한 결과 폴더에 결과물이 저장된다. 특히 "include"폴더 필요.

 

Local Project 만들기.(EXE, DLL)
- Opencv의 Link혹은 Process오류(에러)를 제거 하기위해.
되도록 Link 구조는 동일 하게 유지 하자.
구성 속성 ->일반 -> MFC 사용 : "공유 DLL에서 MFC 사용"
구성 속성 ->C/C++ ->코드 생성->런타임 라이브러리 :"다중 스레드 디버그 DLL(/MDd and /MT)

'작업 > OpenCV' 카테고리의 다른 글

CvvImage 추가 3.4 까지  (0) 2021.11.09
처리시간 측정  (0) 2020.07.17
OpneCV Test(4.1.2, 3.8.4, 3.4.0)  (0) 2019.11.22
OpenCV 4.x.x 사용 C++ Runtime Library Debug  (0) 2019.11.20
OpenCV Memory Leak  (0) 2019.11.20

Expression: __acrt_first_block == header

 

void MatTestVector(Mat *pProcImg)
{
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;

	cv::findContours(*pProcImg, contours, hierarchy, 
    RetrievalModes::RETR_EXTERNAL,
    ContourApproximationModes::CHAIN_APPROX_NONE);
}

 

오류 발생

분석.

- vector가 선언되고 findcontoures()가 실행 후 발생.

(Release Mode에서는 미 발생.)

 

-OpneCV 3.2.0에서 IplImage와 CvSeq사용 시 미 발생.

void MatTestVector(IplImage *pTargetImg)
{
	CvMemStorage *storage = cvCreateMemStorage();
	CvSeq *contours = nullptr;
	CvSeq *contour = nullptr;
	cvFindContours(pTargetImg, storage, &contours, sizeof(CvContour), 
    				CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
}

 

방법.

1. Vector의 선언을 전역으로 변경.

2. Vector의 선언을 1번과 같은 방법 이지만 "static"으로 선언.(사용중)

void MatTestVector(Mat *pProcImg)
{
	static vector<vector<Point> > contours;
	static vector<Vec4i> hierarchy;

	cv::findContours(*pProcImg, contours, hierarchy, 
    				RetrievalModes::RETR_EXTERNAL, 
                    ContourApproximationModes::CHAIN_APPROX_NONE);
}

*정확한 원인과 해결 방법을 아시는 분은 댓글 부탁드립니다.

 

<참고>

STL에 객체가 선언되고, DLL 내부에서 메모리를 할당 메모리 해제 순서에 의해 발생.

==> Expression: __acrt_first_block == header

App와 DLL의 메모리 관리

* App 메모리 생성 -> DLL에서 사용 -> App에서 해지.

* App DLL 함수 호출 -> DLL안에서 메모리 생성 -> DLL안에서 사용 -> DLL 안에서 메모리 해지 -> APP의 결과 전달.

즉, 메모리를 생성한 곳에서 해지 하자.

(App에서 생성하였으면 App에서, DLL에서 생성한 것이면 DLL에서 해지 하자~~!!!)

 

Expression: __acrt_first_block == header

'작업 > OpenCV' 카테고리의 다른 글

CvvImage 추가 3.4 까지  (0) 2021.11.09
처리시간 측정  (0) 2020.07.17
OpneCV Test(4.1.2, 3.8.4, 3.4.0)  (0) 2019.11.22
OpenCV 컴파일(3.4.0, 3.4.8, 4.1.2)  (0) 2019.11.21
OpenCV Memory Leak  (0) 2019.11.20

+ Recent posts