intel xeon phi coprocessor 使用offload方式進行計算時,能夠利用__MIC__的宏來條件編譯代碼,以區分在host cpu上的代碼和在MIC協處理器上的代碼。這對於那些只針對MIC纔有的KNC指令特別有用。它的使用方式相似於:html
#ifdef __MIC__linux
//do something on mic函數
#elseurl
//do something on cpurest
#endifcode
可是,__MIC__ 不能用在offload編譯指令中:htm
#pragma offload target(mic:n)blog
{教程
//__MIC__不能用在這裏ip
}
這是由於,在編譯過程以前,會進行預處理,這個預處理的過程是將CPU端的數據傳遞給MIC協處理器會用到的offload數據,而預處理過程在
#ifdef __MIC__
#else
之間的內容,預處理器不可見,因此,傳遞給MIC的數據操做被略掉,這將發生未可知的錯誤,例如:offload error: unexpected number of variable descriptors
甚至,在宏之間原本應該發生的操做,並無按照預想的執行。
解決方案就是:不要在offload編譯指令中使用__MIC__宏!
——————————————————————————————————————————————————————————————————————————
最可怕的問題是silence error,沒有之一,特別是在一個大程序中,這樣的錯誤查無可查。這個問題困擾了我一天一晚上,最後經過intel developer zone解決:
下面是個人提問:
https://software.intel.com/en-us/forums/topic/540140
Kevin Davis 提到的方法其實並不可取,最好的辦法就是不要在#pragma offload中使用__MIC__
若是你在#pragma offload語句中的KNC指令函數,在連接時碰見:undefined reference to "_mm512_extpackstorelo_epi32"這樣的錯誤,能夠用過這樣的方式解決:
__forceinline __m512i PackStoreLo_epi32(const void*__restrict__ mt, __m512i& v1, _MM_DOWNCONV_EPI32_ENUM conv, int hint)
{
#ifdef __MIC__
return _mm512_extpackstorelo_epi32(mt,v1,conv,hint);
#else
return v1;
#endif
}
下面是我找到的資料:
https://software.intel.com/en-us/blogs/2013/03/27/painful-potential-problems-the-mic-macro-and-offload-code-blocks
(url中竟然寫着painful-potential-problems,=、=!)