2013-07-03 61 views
0

JAVA我的項目中我一般必須乘以巨大的數組與標量。所以我想通過採用所謂的loop unrolling來寫一個方法。到目前爲止,我想出了這一點:數組時間標量:循環展開

public static float[] arrayTimesScalar(float[] array, float scalar){ 
int n = array.length; 
float[] result = new float[n]; 
int m = n % 7; 
if(n == 0){ throw new Error("The input array must,at least, hold one element"); } 

if (n < 7){ 
    for(int i = 0; i < 7; i++){ 
     result[i] = scalar*array[i]; 
    } // end for 
} 
else{ 
    if (m != 0){ 
     for(int i = 0; i < m; i++){ 
      result[i] = scalar*array[i]; 
     } 
     for(int i = m; i < n; i += 7){ 
      result[i] = scalar*array[i]; 
      result[i + 1] = scalar*array[i + 1]; 
      result[i + 2] = scalar*array[i + 2]; 
      result[i + 3] = scalar*array[i + 3]; 
      result[i + 4] = scalar*array[i + 4]; 
      result[i + 5] = scalar*array[i + 5]; 
      result[i + 6] = scalar*array[i + 6]; 
     } 
    } 
    else{ 
     for(int i = 0; i < n; i += 7){ 
      result[i] = scalar*array[i]; 
      result[i + 1] = scalar*array[i + 1]; 
      result[i + 2] = scalar*array[i + 2]; 
      result[i + 3] = scalar*array[i + 3]; 
      result[i + 4] = scalar*array[i + 4]; 
      result[i + 5] = scalar*array[i + 5]; 
      result[i + 6] = scalar*array[i + 6]; 
     } 
    } 
}  
return result; 

}

我會很感激的瞭解,如果該方法是正確的,在現在看來,如果使用循環展開,還沒有使任何意義,儘管higly優化編譯器。

+0

要確定它是否正確,您應該編寫一些單元測試。要確定它是否有意義,您應該對它進行基準測試。 –

+2

JIT編譯器將爲您執行循環展開 - 如果您需要優化代碼的一部分,有更好的方法可以花費時間。讓JIT完成工作最好的辦法是編寫簡單而直接的代碼 - 就你的情況而言:一個簡單的for循環,其中1個增量就像你用於'n <7'的循環。 – assylias

回答

2

循環展開是一種低級別的優化,它在現代JVM中很可能沒有意義。但是,您不應該猜測或詢問其他人:您應該在目標系統上測試您的代碼並測量性能。例如,通過編寫單元測試,我相信這也很容易驗證。你的代碼沒有什麼明顯的錯誤。

0

根據你的n有多大以及時間限制有多困難,你可以在一段時間內將乘法並行化爲安全。但這當然是一個巨大的變化,但我認爲這種高層次的變化是提高績效的唯一選擇。

循環展開等「瑣碎」事情由編譯器和運行時的JIT完成。