Iwao Dev

気付いたことをメモしています.

この画面は、簡易表示です

VC OpenMP

ループ部分の OpenMP 対応

効果は低かったが,OpenMP を利用したコードに書きなおしてみた.


//---	オリジナルのコード  ----------------------------------------------------------------
	Ld2A	lins ;
	{
		for (size_t indexVV=0 ; indexVV<vv_plf.size() ; indexVV++) {
			v_PLF	v_plf = vv_plf[indexVV] ;
			if (v_plf.size() == 0)		{	continue ;		}
			for (size_t indexV=0 ; indexV<v_plf.size() ; indexV++) {
				PLF	plf = v_plf[indexV] ;
				if (plf.Is_line()) {
					Vd4A	v4a = plf ;
					Vd3A	v3a = ::ToVd3A(v4a) ;
					Vd2A	v2a = ::ToVd2A(v3a) ;
					for (size_t indexL=1 ; indexL<v2a.size() ; indexL++) {
						Vd2	s = v2a[indexL-1] ;
						Vd2	e = v2a[indexL-0] ;
						Ld2	lin(s,e) ;
						lins.push_back(lin) ;
						}
					}
				}
			}
		}
//----	OpenMP 対応 ------------------------------------------------------------------------
Ld2A	PLF_to_Ld2A	(const v_PLF& v_plf)
{
	Ld2A	lins ;
	{
		for (size_t indexV=0 ; indexV<v_plf.size() ; indexV++) {
			PLF	plf = v_plf[indexV] ;
			if (plf.Is_line()) {
				Vd4A	v4a = plf ;
				Vd3A	v3a = ::ToVd3A(v4a) ;
				Vd2A	v2a = ::ToVd2A(v3a) ;
				for (size_t indexL=1 ; indexL<v2a.size() ; indexL++) {
					Vd2	s = v2a[indexL-1] ;
					Vd2	e = v2a[indexL-0] ;
					Ld2	lin(s,e) ;
					lins.push_back(lin) ;
					}
				}
			}
		}
	return	lins ;
	}

Ld2A	PLF_to_Ld2A	(const vv_PLF& vv_plf)
{
	Ld2A	lins ;
	{
		#ifdef	_OPENMP
			#pragma	omp	parallel for
		#endif
		for (long indexVV=0 ; indexVV<long(vv_plf.size()) ; indexVV++) {
			v_PLF	v_plf = vv_plf[indexVV] ;
			if (v_plf.size() == 0)		{	continue ;		}
			Ld2A	ln_a = ::PLF_to_Ld2A(v_plf) ;
			#ifdef	_OPENMP
				#pragma	omp	critical	(PLF_to_Ld2A)
			#endif
			{
				lins.insert(lins.end(),ln_a.begin(),ln_a.end()) ;
				}
			}
		}
	return	lins ;
	}

C:\Users\Iwao>C:\Temp\Test\Fill\GetX_1\ReleaseS.140\GetX_1.exe
31.856

C:\Users\Iwao>C:\Temp\Test\Fill\GetX_1\Release.140\GetX_1.exe
20.202

C:\Users\Iwao>

v_Vd2A	GetCross	(const vv_PLF& vv_plf,const Vd2& pt)
{
	Ld2A	lins = ::PLF_to_Ld2A(vv_plf) ;
	v_Vd2A	v_pnts ;
	{
		Vd2A	pnts ;
		pnts.push_back(pt) ;
		v_pnts.push_back(pnts) ;
		}
	{
		Ld2		lh(pt,pt+Vd2(1,0)) ; 
		Ld2		lv(pt,pt+Vd2(0,1)) ; 
		Vd2A	work_pnts ;
		#ifdef	_OPENMP
			#pragma	omp	parallel for
		#endif
		for (long index=0 ; index<long(lins.size()) ; index++) {
			Vd2	s = lins[index].S ;
			Vd2	e = lins[index].E ;
			Ed2	ext(s,e) ;
			Vd2	x ;
			if (get_cross_line(s,e,lh.S,lh.E,&x)) {
				if (::Is_point_in_extent(x,ext)) {
				//	pnts.push_back(x) ;
					}
				}
			if (get_cross_line(s,e,lv.S,lv.E,&x)) {
				if (::Is_point_in_extent(x,ext)) {
				//	pnts.push_back(x) ;
					}
				}
			{
				Vd2	h = ::get_near_on_line(s,e,pt) ;
				if (::Is_point_in_extent(h,ext)) {
					#ifdef	_OPENMP
						#pragma	omp	critical	(GetCross)
					#endif
					{
						work_pnts.push_back(h) ;
						if (work_pnts.size() > 10) {
							v_pnts.push_back(work_pnts) ;
							work_pnts.clear() ;
							}
						}
					}
				}
			}
		v_pnts.push_back(work_pnts) ;
		}
	return	v_pnts ;
	}



  にほんブログ村 IT技術ブログへ


実行時のエラー OpenMP

普段通っているコードなのに,ある条件(操作)で実行時にエラー.
エラーの場所はある範囲(DelFileE への登録)ではあるが,固定されてない.
 CStringArray に CString の追加.
コールスタックを見ると MakeFace$omp$1 とある.


   ucrtbased.dll!__VCrtDbgReportA () 不明
   ucrtbased.dll!__CrtDbgReport () 不明
   mfc140ud.dll!AfxAssertFailedLine(const char * lpszFileName, int nLine) 行 333 C++
   mfc140ud.dll!CWnd::DestroyWindow() 行 1055 C++
   mfc140ud.dll!CToolTipCtrl::DestroyToolTipCtrl() 行 73 C++
   mfc140ud.dll!AFX_MODULE_THREAD_STATE::~AFX_MODULE_THREAD_STATE() 行 253 C++
   mfc140ud.dll!AFX_MODULE_THREAD_STATE::`scalar deleting destructor'(unsigned int) C++
   mfc140ud.dll!CThreadSlotData::DeleteValues(CThreadData * pData, HINSTANCE__ * hInst) 行 354 C++
   mfc140ud.dll!CThreadSlotData::DeleteValues(HINSTANCE__ * hInst, int bAll) 行 396 C++
   mfc140ud.dll!AfxTermLocalData(HINSTANCE__ * hInst, int bAll) 行 494 C++
   mfc140ud.dll!DllMain(HINSTANCE__ * hInstance, unsigned long dwReason, void * __formal) 行 663 C++
   mfc140ud.dll!dllmain_dispatch(HINSTANCE__ * const …, void * const reserved) 行 195 C++
   mfc140ud.dll!_DllMainCRTStartup(HINSTANCE__ * const …, void * const reserved) 行 248 C++
   ntdll.dll!_LdrpCallInitRoutine@16 () 不明
   ntdll.dll!_LdrShutdownProcess@0 () 不明
   ntdll.dll!_RtlExitUserProcess@4 () 不明
   kernel32.dll!_ExitProcessStub@4 () 不明
   ucrtbased.dll!__crt_hmodule_traits::close(struct HINSTANCE__ *) 不明
   ucrtbased.dll!__crt_hmodule_traits::close(struct HINSTANCE__ *) 不明
   ucrtbased.dll!__Exit () 不明
   ucrtbased.dll!_raise () 不明
   ucrtbased.dll!__acrt_lock_and_call<class <lambda_fe…55> >(enum __acrt_lock_id,class <…; &&) 不明
   ucrtbased.dll!___acrt_MessageWindowA () 不明
   ucrtbased.dll!__VCrtDbgReportA () 不明
   ucrtbased.dll!__CrtDbgReport () 不明
   mfc140ud.dll!AfxAssertFailedLine(const char * lpszFileName, int nLine) 行 333 C++
   mfc140ud.dll!CStringArray::SetSize(int nNewSize, int nGrowBy) 行 165 C++
   mfc140ud.dll!CStringArray::SetAtGrow(int …, const ATL::CStringT<wchar_t,… > & newElement) 行 265 C++
   mfc140ud.dll!CStringArray::Add(const ATL::CStringT<wchar_t, … > & newElement) 行 322 C++
   BlockIn.exe!DelFileE::Add(const wchar_t * fileName) 行 51 C++
   BlockIn.exe!CacheFile::GetCF_Name(const wchar_t * srcName, const unsigned int dibWidth) 行 415 C++
   BlockIn.exe!PartsA_To::ToIPX(const wchar_t * ipxName) 行 257 C++
   BlockIn.exe!PartsA_To::DumpDebug(const int delFE, const wchar_t * pre_) 行 297 C++
   BlockIn.exe!PartsA_To::DumpDebug(const wchar_t * pre) 行 47 C++
   BlockIn.exe!PartsA_Fnc_DebugDump(PartsA & partsAry, const wchar_t * pre) 行 818 C++
   BlockIn.exe!MaPat__DebugDump(const Parts & parts) 行 3293 C++
   BlockIn.exe!MaPat::MakePartsFace(const int makeEdge) 行 3481 C++
   BlockIn.exe!BAPat::MakePartsFace(const int makeEdge) 行 1508 C++
   BlockIn.exe!BAPat::GetPartsFace(const int makeEdge) 行 1935 C++
   BlockIn.exe!BlockInf::MakeFace(const int makeEdge) 行 3465 C++
> BlockIn.exe!BlockLay::MakeFace$omp$1() 行 4320 C++
   [外部コード]


次の様に #pragma omp critical を追加.
  BOOL DelFileE::Add (LPCTSTR fileName)
  {
     #ifdef _OPENMP
       #pragma omp critical (DelFileE_Add)
     #endif
     {
       CString filePath = ::FolderDelLastSP(fileName) ;
       DelFileName.Add(filePath) ;
       }
     return TRUE ;
     }



  にほんブログ村 IT技術ブログへ


MessageBar クラスと OpenMP

新しい Message クラスを使用して,OpenMP 対応の動作のテスト.
void CTSttBView::OnTestDrawBar2()
{
  Message tmp ;
  ElapseTick et ;
  #define BAR_COUNT_2 1000000
  #ifdef _OPENMP
    #pragma omp parallel for
  #endif
  for (int i=0 ; i<100 ; i++) {
    Message bar ;
    bar.SetBar (_T(“Test Message 1 M * 100”),BAR_COUNT_2,RGB(0,255,0)) ;
    for (int index=0 ; index<BAR_COUNT_2 ; index++) {
      bar.SetBarInc() ;
      }
    }
  DWORD elapseT = et.GetElapse() ;
  CString str ; str.Format(_T(“%.2f 秒”),elapseT/1000.) ;
  AfxMessageBox(str) ;
  }
1 億回 SetBarInc を呼出していて,10 秒程度だったのが,#pragma omp parallel for で 20 秒程度になってしまった.


inline bool MessageBase::SetBarInc (void)
{
  if (GetBarMax() == 0) { return false ; }
  if (GetBarCount() < GetBarMax()) { B_Counter++ ; }
  else { B_Counter = 0 ; } // reset
  IncCounterR() ;
  {
    long lastPos = long(100*(GetBarCount()-1)/GetBarMax()) ;
    long new_Pos = long(100*(GetBarCount()-0)/GetBarMax()) ;
    if (lastPos == new_Pos) { return true ; }
    }
  #ifdef _WINDOWS
  #ifdef _MFC_VER
  #ifdef _OPENMP
    if (AfxGetMainWnd() == NULL) { return false ; }
  #endif
  #endif
  #endif
  return SetBarCount(B_Counter) ;
  }
AfxGetMainWnd() を呼出す回数を減らすことにより,3 秒程度に.



  にほんブログ村 IT技術ブログへ


~iDocText でダウン

先日作成した TextureToPath 関係でダウンする様になってしまった.
場所は,iDocText のデストラクタ付近.
呼出し元をたどると,#pragma omp parallel for .


TextureCopy::GetDrawName に #pragma omp critical (TextureCopy_GetDrawName) を追加.



  にほんブログ村 IT技術ブログへ


vcompd.dll が見つからなかったため …

VC 8 で FBXtoPA を OpenMP に変更してビルド,実行すると
—————————
FBXtoPA.exe – コンポーネントが見つかりません
—————————
vcompd.dll が見つからなかったため、このアプリケーションを開始できませんでした。
アプリケーションをインストールし直すとこの問題は解決される場合があります。
—————————
OK
—————————
OpenMP_Debug_Error
検索すると,omp.h のインクルードがないための現象.
アプリケーションクラスのソースに,以下を追加して OK .
  #ifdef _OPENMP
  #include <omp.h>
  #endif



  にほんブログ村 IT技術ブログへ


OpenMP エラー 1002

—————————
致命的なユーザー エラー 1002:
—————————
同一名の 1 つで ‘#pragma omp critical’ が不適切に入れ子にされています

2.9 ディレクティブの入れ子

ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ja/dv_vcopenmp/html/6565a43c-fd2d-4366-8322-8d75e1b06600.htm

http://msdn.microsoft.com/ja-jp/library/azb90x99(v=VS.80).aspx

局所的になる様に,呼び出し元での "#pragma omp critical" を削除.

class Profile {
  …
protected:
    LPCTSTR  LastProfileName ;
    CString     C_T_ProfileName ;
  …
  } ;

BOOL Profile::SaveProfileName(void)
{
  CWinApp* app = AfxGetApp() ;
  if (app== NULL) { return FALSE ; }
  LastProfileName = AfxGetApp()->m_pszProfileName ;
  AfxGetApp()->m_pszProfileName = C_T_ProfileName ;
  return TRUE ;
  }
BOOL Profile::LoadProfileName(void)
{
  AfxGetApp()->m_pszProfileName = LastProfileName ;
  return TRUE ;
  }

omp critical ではなく,MFC 同期クラスを使用する様に変更.
//  以下は,テスト用のコード  
BOOL Profile::?et??? (LPCTSTR lpszSection,LPCTSTR lpszEntry,…)
{
    … 
    CMutex m(FALSE,MN_LPN) ;
    m.Lock() ;
// return        ???Profile??? (lpszSection, lpszEntry, …) ;
    BOOL ret = ???Profile??? (lpszSection, lpszEntry, …) ;
    m.Unlock() ;
    return ret ;
    }
//  MFC 同期クラスの呼出しはコストがかからない様に修正する 



  にほんブログ村 IT技術ブログへ



    top

    %d人のブロガーが「いいね」をつけました。