2015-12-05 36 views
2

這與我的文章here有些相關。高效地從矢量拉任意切片

我想在Rust中實現矩陣乘法,我認爲爲了有效地做到這一點,我需要能夠從矩陣中獲取列數據。這很難,因爲我以矩陣格式存儲矩陣。

我正在使用展開的網點產品實現,詳情請參閱上述link以及我以前的question。我希望能夠從一個矩陣和另一個矩陣的列中提供此方法。

如何從我的矩陣中有效選擇列數據?更一般地說:我如何選擇任意數據模式(如R,matlab,numpy等)?

我已經試過:

  1. 使用跨入視圖和收集迭代器 - 這似乎過於緩慢。
  2. 使用標準的循環迭代,但這似乎不是由鏽編譯器矢量化。
+3

我覺得你錯過了上下文。例如,爲什麼不能直接使用跨步視圖?你可以先調整整個(sub? - )矩陣,並重復這個工作嗎?什麼不是矢量化的? - 也許我們可以解決這個問題。 – Veedrac

+2

即使識別出一個循環的循環,LLVM也不一定會自動化一個循環,請參閱http://llvm.org/docs/Vectorizers.html#scatter-gather – bluss

回答

1

如果你使用更聰明的循環,你會得到你的問題的答案。我的意思是,如果您重新排序for循環,則不必從矩陣中抽出一列。這樣,你可以保持CPU緩存溫暖。

如果您當前的算法是這樣的:

// traditional multiplication 
for i in 0..a_rows { 
    for j in 0..b_cols { 
     for k in 0..a_cols { 
      c[i][j] += a[i][k] * b[k][j]; 
     } 
    } 
} 

你產生由於B [k]和很多高速緩存未命中的研究[J]不訪問您的數據順序。

for i in 0..a_rows { 
    for k in 0..a_cols { 
     // Note, that j iterates over a column of B 
     for j in 0..b_cols { 
      c[i][j] += a[i][k] * b[k][j]; 
     } 
    } 
} 

如果交換兩個內部循環,則循環遍歷B列,並利用緩存。首先,您將訪問b[k][0],然後訪問b[k][1]等等。如果元素是4字節,則可以直接從緩存訪問下一個12元素(因爲64字節是最常見的L1緩存行大小)。傳統的方法沒有如此有效地使用緩存。