2012-11-23 101 views
1

我們已經給出了使用openmp優化結構不良的程序的任務。我是很新的節目,所以我希望每個人都可以闡明如何優化該功能的一些光(許多我需要優化的一個):對函數的OpenMP優化

void 
entry_type3(F2D *sData, F2D *ones, F2D *quat, F2D **pos, F2D **vel) 
{ 
    //Observation 

    F2D *t; 

    t = fSetArray(1, 3, 0); 
    asubsref(t,2) = -9.8; 


    F2D *accl = fDeepCopyRange(sData, 0, 1, 0, 3); 
    F2D *gtemp = fMtimes(ones, t); 
    F2D *gravity = quatRot(gtemp, quat); 



    fFreeHandle(gtemp); 
    fFreeHandle(t); 

    t = fSetArray(3,3,0); 
    asubsref(t,0) = 1; 
    asubsref(t,4) = 1; 
    asubsref(t,8) = 1; 

    int n = ones->height; 
    int i; 
    for(i=0; i<(t->height*t->width); i++) 
      asubsref(t,i) = asubsref(t,i)/STDDEV_ACCL; 

    F2D *w = mcl(gravity, accl, t); 

    generateSample(w, quat, *vel, *pos); 
    fFreeHandle(t); 


    //Motion model 
    t = fMtimes(ones, accl); 
    fFreeHandle(accl); 
    accl = fMinus(t, gravity); 
    fFreeHandle(w); 
    fFreeHandle(gravity); 
    fFreeHandle(t); 




    F2D *is; 
    #pragma omp parallel sections 
    { 
     #pragma omp section 
     { 
      F2D *is = quatConj(quat); 
      F2D *s = quatRot(*vel, is); 
      fFreeHandle(is); 
      for(i=0; i<(s->height*s->width); i++) 
      { 
       asubsref(s,i) = asubsref(s,i)*acclTimeInterval; 
      } 
      is = fPlus(*pos, s); 
      fFreeHandle(*pos); 
      *pos = fDeepCopy(is); 
      fFreeHandle(is); 
      fFreeHandle(s); 
     } 


     /** pos_ above stores: pos+quatRot(vel,quatConj(quat))*acclTimeInterval **/ 

     #pragma omp section 
     { 
      F2D *is = quatConj(quat); 
      F2D *s = quatRot(accl, is); 
      F2D* t = fDeepCopy(s); 

      for(i=0; i<(s->height*s->width); i++) 
      { 
       asubsref(t,i) = 1/2*asubsref(s,i)*acclTimeInterval*acclTimeInterval; 
      } 

      /** t_ above stores: 1/2*quatRot(accl,quatCong(quat))*acclTimeInterval^2 **/ 

      fFreeHandle(s); 
      fFreeHandle(is); 


s = randnWrapper(n,3); 

      for(i=0; i<(s->height*s->width); i++) 
      { 
       asubsref(s,i) = asubsref(s,i) * M_STDDEV_POS; 
      } 

      /** s_ above stores: randn(n,3)*M_STDDEV_POS **/ 

     is = fPlus(*pos, t); 
      fFreeHandle(*pos); 
     *pos = fPlus(is, s); 

      fFreeHandle(s); 
      fFreeHandle(t); 
      fFreeHandle(is); 
    } 

}   
     //vel=vel+accl*acclTimeInterval+randn(n,3)*M_STDDEV_VEL; 
#pragma omp parallel sections 
{ 
#pragma omp section 
{ 
F2D *t = fDeepCopy(accl); 
#pragma omp parallel for 
    for(i=0; i<(accl->height*accl->width); i++) 
    { 
      asubsref(t,i) = asubsref(accl,i) * acclTimeInterval; 
    } 

    is = fPlus(*vel, t); 
    fFreeHandle(accl); 
    fFreeHandle(t); 
} 
#pragma omp section 
{ 

F2D *s = randnWrapper(n,3); 
#pragma omp parallel for 
    for(i=0; i<(s->height*s->width); i++) 
    { 
      asubsref(s,i) = asubsref(s,i) * M_STDDEV_VEL; 
    } 

    fFreeHandle(*vel); 
    *vel = fPlus(is, s); 
    fFreeHandle(is); 
    fFreeHandle(s); 
} 
} 
} 

我已經添加了幾個OpenMP的相似之處,但它仍然是跑得非常緩慢,所以我希望如果你老練的老將能指出我應該看哪些位置來提高表現。

+0

您正在使用OpenMP部分。你真的確定,這兩個代碼段(在每個'section'結構中)是否可以獨立執行,即它們之間沒有數據依賴關係?非常緩慢的執行通常是線程之間共享(虛假)的標誌。 –

回答

0

現在,它看起來只是在一些詭計中卡住了一些pragma,而不關心代碼的並行性質。現在,你並沒有真正分裂你的處理器的工作,你基本上是通過讓每個核心都做同樣的事情來重複努力的(並且可能會產生一些嚴重的錯誤答案)。很高興看到原件,看看你有什麼改變。實際上,您需要以編程方式分割任務(例如,如果您正在處理圖像,則需要告訴處理器1執行奇數像素,處理器2執行偶數像素,OpenMP不夠聰明,無法解決問題)。我很抱歉,如果這看起來沒有那麼有用,但是說這是爲了一項任務,我認爲你可能需要爲自己找出一定數量 - 但重要的是OpenMP不能只是讓代碼並行,你需要告訴它如何。看看omp_get_num_threads()和omp_get_thread_num()。

+0

謝謝你,其實非常有幫助,我在想同樣的事情(關於我只是把它編譯爲編譯指令)問題是我無法看到哪些部分可以並行運行,因爲變量都是看似連接的並且應該一個接一個地執行,我希望提供一些關於如何成功分離代碼的提示,主要是 – Joe

+0

因此,我可能不會給這個應有的正義,但請看一下這裏: 'for(i = 0; i <(s-> height * s-> width); i ++){asubsref(s,i)= asubsref(s,i)* M_STDDEV_POS;}'。它看起來並不像這個位依賴於序列(儘管有處理方法 - 我只是沒有足夠的資格來談論它們),所以假設我做了它而不是'int k = numProcessors; int MaxI = s-> height * s-> width; int procNum = processorNumber; for(int i = procNum; i deftfyodor

0

此代碼在開始處: for(i=0; i<(t->height*t->width); i++) asubsref(t,i) = asubsref(t,i)/STDDEV_ACCL; 可能會被有效並行化。每個i的計算是完全獨立的。

尋找這樣獨立的代碼部分。當然,你應該考慮並行化。