2014-04-24 54 views
0

我在主機openMP代碼中使用了intel的卸載編譯指示。代碼如下所示從主機openMP並行區域執行Xeon-Phi異步卸載

int s1 = f(a,b,c); 

#prama offload singnal(s1) in (...) out(x:len) 
{ 
    for (int i = 0; i < len; ++i) 
    { 
     x[i] = ... 
    } 
} 

#pragma omp parallel default(shared) 
{ 
    #pragma omp for schedule(dynamic) nowait 
    for (int i = 0; i < count; ++i) 
    { 
     /* code */ 
    } 

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j) 
    { 
     /* code */ 
    } 
} 

#pragma offload wait(s1) 
{ 
    /* code */ 
} 

將$ x $代碼卸載計算到MIC。代碼通過確定一些openMP到CPU核心來保持自己的繁忙。上面的代碼按預期工作。然而,第一個卸載雜注花費很多時間,併成爲瓶頸。儘管如此,總的來說,它可以將$ x $的計算轉移到MIC上。潛在克服我想這個延遲問題的一種方法是如下

int s1 = f(a,b,c); 

#pragma omp parallel default(shared) 
{ 
    #pragma omp single nowait 
    { 
     #prama offload singnal(s1) in (...) out(x:len) 
     { 
      for (int i = 0; i < len; ++i) 
      { 
       x[i] = ... 
      } 
     } 

    } 

    #pragma omp for schedule(dynamic) nowait 
    for (int i = 0; i < count; ++i) 
    { 
     /* code */ 
    } 

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j) 
    { 
     /* code */ 
    } 
} 

#pragma offload wait(s1) 
{ 
    /* code */ 
} 

所以這個新的代碼,分配一個線程來完成卸載,而其他的OpenMP線程可用於其它工作分享結構。但是,此代碼不起作用。我收到以下錯誤消息

device 1 does not have a pending signal for wait(0x1) 

卸載報告指出上面的一段代碼是主要的罪魁禍首。一個臨時工作是使用常數作爲信號,即信號(0),該信號起作用。但是,我需要一個更持久的解決方案。任何人都可以爲我的代碼中出現問題的地方提供照明。

謝謝

+0

這是https://software.intel.com/en-us/forums/topic/509845 – Jeff

回答

0

我不能評論第二個代碼塊。我有一些關於第一個的觀察。

第一次卸載總是需要較長時間,因爲它還設置卸載基礎結構。這種結構包括諸如傳遞環境變量,複製libomp5的話筒實現,設置線程池等等。

避免這種情況的方法是首先設置一個虛擬卸載,這意味着它不會真的做到任何東西都不是你計算塊的一部分。

有關優化至強協處理器的一系列優秀參考資料位於software.intel.com/mic-developer的培訓選項卡下。

另請參見software.intel.com/en-us/articles/programming-and-compiling-for-intel-many-integrated-core-architecture,software.intel.com/en-us/articles /優化和性能調優for intel-xeon-phi-coprocessors-part-1-optimization,以及software.intel.com/en-us/articles/optimization-and-performance-tuning-for-intel-至強-PHI-協處理器部分-1-優化。

對不起,長URL,但stackoverflow不允許我包含兩個以上的鏈接,因爲我是新的。

+0

感謝您的答覆的副本。這整個代碼塊在順序for循環內。因此函數在外部for循環的每次迭代中被調用。初始化在外部for循環之前完成。這個初始化在我的情況下需要7秒鐘(由於malloc數量龐大)。在進行一輪malloc之後,每個分配區域都被「重用」。我一直忽略這7秒鐘。這是內部外循環,每個MIC卸載需要4毫秒,這正是我想要隱藏的內容。 – zimbra314

1

讓我補充一下泰勒的回覆。

由於初始化事件正在進行,第一次卸載確實需要比後續卸載更多的時間。泰勒勾畫出了一些正在發生的事情。您可以通過使用環境變量OFFLOAD_INIT = on_start來避免虛擬卸載。這應該讓運行時系統提前完成所有初始化。這種開銷不會消失,但它會從您的第一次卸載轉移到應用程序初始化。

您的第二個代碼段的問題似乎是您的卸載目標設備不同。信號和等待只有在信號和等待發生在同一個目標設備上時纔有效。由於您沒有在卸載時明確使用target(mic:0)子句,因此運行時系統選擇不同目標設備的可能性很高。

我想提出的一個建議是不使用純整數的信號。通常,信號表明某個緩衝區已準備就緒。在這些情況下,最好使用緩衝區指針作爲信號句柄,因爲它對於使用不同緩衝區的並行卸載將是唯一的。

乾杯, -Michael

+0

他們瞄準相同的設備。即麥克風:1。這是明確的 – zimbra314