2015-04-16 28 views
0

我已經聲明瞭一些全局變量是_Cilk_shared。它們用於我想卸載的函數中它們用於某些我不想被卸載的函數。爲什麼使用_Cilk_offload卸載需要每個函數都是_Cilk_shared?

所以最初我只聲明瞭那些我需要作爲_Cilk_shared卸載並使用_Cilk_offload調用這些函數的函數。

它編譯得很好。當我在主機上運行它時,它會給出正確的結果。

然後我用MIC運行它。它給我運行時錯誤關於無法加載庫blablabla未定義的符號,其次是函數名稱,我沒有聲明爲_cilk_shared。這些功能也不需要爲_cilk_shared。

所以我必須將這些函數更改爲_cilk_shared。再次運行它。這次MIC提供了正確的結果。

我查(我不想卸載和最初_cilk_shared沒有申報)這些功能是否卸載與否,利用

#ifdef __MIC__ 
    printf(" Running on MIC\n"); 
#else 
    printf("No MIC\n"); 
#endif 

的結果是,他們不卸載.. ..

所以我想知道爲什麼它要我聲明這些函數爲_Cilk_shared?

回答

0

當一個函數被聲明爲卸載 - 函數是否在該文件中定義,編譯器生成 對象的代碼,將在處理器和目標代碼運行將 在協處理器上運行。 如果函數在該文件中使用時,它 產生目標碼,將調用處理器版本和代碼 ,將調用協處理器版本(除非該呼叫是受「‘的ifdef MIC’保護的 區域內

那麼爲什麼裝載程序想要一個函數被聲明爲卸載,即使你從不在卸載區域調用它? 那麼如果函數是類的一部分,那麼需要聲明整個類用於卸載因爲類'知道'什麼函數是它的一部分,當你爲一個類加載對象代碼時,你加載了整個類,在這種情況下,如果你要共享那個類的對象,它應該被聲明爲_Cilk _共享。

如果函數處於動態鏈接庫中,則可能會遇到類似的問題。動態鏈接庫「知道」哪些功能是它的一部分,它知道它需要哪些功能。所以,當你運行你的代碼時,加載器想要找到它需要的庫「知道」的所有文件。在這種情況下,最簡單的方法就是製作所有庫的卸載版本。您可以嘗試其他方法 - 嘗試靜態鏈接包含這些文件的庫,或者嘗試創建不知道它們需要的東西的庫 - 將它們分割成幾部分或嘗試明確創建單獨的主機和協處理器版本該庫就像您要在協處理器上本地運行的代碼一樣。

如果這不能解釋你所看到的,請告訴我。

+0

我寫的這些函數都沒有動態鏈接或共享類中的成員函數。他們只是在一個頭文件中聲明.. – yidiyidawu

+0

感嘆,你有可能把一個小的測試用例放在一起,顯示這種行爲?它看起來可能需要更多的挖掘才能弄清楚。 – froth

相關問題