2010-04-29 80 views
0

我正在處理一些代碼,我試圖儘可能地優化它,基本上它在一定的時間限制內運行。在C++中實現SIMD

下使電話...

static affinity_partitioner ap; 
parallel_for(blocked_range<size_t>(0, T), LoopBody(score), ap); 

...和下​​面是指在執行什麼。

void operator()(const blocked_range<size_t> &r) const { 

    int temp; 
    int i; 
    int j; 
    size_t k; 
    size_t begin = r.begin(); 
    size_t end = r.end(); 

    for(k = begin; k != end; ++k) { // for each trainee 
     temp = 0; 
     for(i = 0; i < N; ++i) { // for each sample 
      int trr = trRating[k][i]; 
      int ei = E[i];    
      for(j = 0; j < ei; ++j) { // for each expert 
       temp += delta(i, trr, exRating[j][i]); 
      } 
     }   
     myscore[k] = temp; 
    } 
} 

我正在使用英特爾的TBB來優化這個。但我也一直在閱讀有關SIMD和SSE2以及這些性質的內容。所以我的問題是,如何將變量(i,j,k)存儲在寄存器中,以便可以通過CPU更快地訪問它們?我認爲答案與實施SSE2或其一些變體有關,但我不知道如何做到這一點。有任何想法嗎?

編輯:這將在Linux機器上運行,但使用英特爾編譯器我相信。如果有幫助,我必須在執行任何操作之前運行以下命令以確保編譯器正常工作... source /opt/intel/Compiler/11.1/064/bin/intel64/iccvars_intel64.csh; source /opt/intel/tbb/2.2/bin/intel64/tbbvars.csh ...然後編譯我做:icc -ltbb test.cxx -o test

如果沒有簡單的方法來實現SSE2,任何關於如何進一步優化代碼的建議?

感謝, 斯托伊奇

+1

編譯器應該爲你做這種事情。 – zdav 2010-04-29 16:57:10

+1

@zdav:C++的語義排除了向量化,因爲默認情況下,指針可能是未對齊的或別名的。 – Potatoswatter 2010-04-29 16:58:59

+0

ICC允許您在代碼中提供嵌入的提示,以幫助它更好地進行矢量化。當然,如果你無法控制提供的數據等等,那麼這不會有太大的幫助。 – 2010-04-29 18:20:12

回答

1

你的問題代表了一些混亂的事情。假設你正在編譯優化(你應該這樣做 - 在你的icc調用中加入「-O2」),那麼i,j,k變量幾乎肯定會保存在寄存器中。

您可以使用asm塊,但考慮到您已經在使用ICC,更簡單的方法是使用SSE內在函數。英特爾爲他們的文檔在這裏 - http://www.intel.com/software/products/compilers/clin/docs/ug_cpp/comm1019.htm

它看起來像你可以SIMD化的頂級循環,雖然它將取決於你的delta函數是什麼。

+0

我無法控制icc調用。這是一項家庭作業,所以我的能力非常有限。我甚至不能編輯完全可以優化的delta函數。我會搗鼓asm區塊的想法。謝謝。 – Hristo 2010-04-29 17:16:23

+0

@Hristo:Intrinsics應該給你比asm塊更少的麻煩。但是看看自動矢量化。您應該能夠找到仿效控制命令行標誌的'#pragma'命令。 – Potatoswatter 2010-04-29 20:24:32

0

如果你使用GCC,見http://gcc.gnu.org/projects/tree-ssa/vectorization.html對於如何幫助編譯器自動向量化你的代碼和示例。

否則,您需要告訴我們您正在使用的平臺。

+0

這將在Linux機器上運行,但使用英特爾編譯器我相信。如果有幫助,我必須在執行任何操作之前運行以下命令以確保編譯器正常工作... source /opt/intel/Compiler/11.1/064/bin/intel64/iccvars_intel64.csh; source /opt/intel/tbb/2.2/bin/intel64/tbbvars.csh ...然後編譯我做:icc -ltbb test.cxx -o test – Hristo 2010-04-29 16:59:08

+0

http://www.advogato.org/article/871.html是舊的,但看起來很相關。 '-xW -O2 -vec-report3'。並查看'man icc'並搜索'vector'。 – Potatoswatter 2010-04-29 17:11:33

1

當您想在C++模塊中使用匯編語言時,您可以將它放入asm塊中,並繼續在塊之外使用您的變量名稱。您在asm塊中使用的彙編指令將指定正在操作哪個寄存器等,但它們將因平臺而異。

+0

你能告訴我一個例子嗎? – Hristo 2010-04-29 16:59:36

0

編譯器應該爲你做這件事。例如,在VC++中,您可以簡單地打開SSE2。

+0

SSE2自動矢量化是icpc的默認選項,g ++是完全正常的選項。從你展示的很少的外觀來看,它可能需要交換內部循環以及允許內聯擴展該功能。這對於顯式simd問題更是如此。爲什麼 – tim18 2016-06-27 20:33:14