効果は低かったが,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 ; }