有一個函式可以像往常一樣將兩個矩陣相乘
public IMatrix Multiply(IMatrix m1, IMatrix m2)
{
var resultMatrix = new Matrix(m1.RowCount, m2.ColCount);
for (long i = 0; i < m1.RowCount; i )
{
for (byte j = 0; j < m2.ColCount; j )
{
long sum = 0;
for (byte k = 0; k < m1.ColCount; k )
{
sum = m1.GetElement(i, k) * m2.GetElement(k, j);
}
resultMatrix.SetElement(i, j, sum);
}
}
return resultMatrix;
}
這個函式應該用Parallel.ForEach Threading重寫,我試過這種方式
public IMatrix Multiply(IMatrix m1, IMatrix m2)
{
// todo: feel free to add your code here
var resultMatrix = new Matrix(m1.RowCount, m2.ColCount);
Parallel.ForEach(m1.RowCount, row =>
{
for (byte j = 0; j < m2.ColCount; j )
{
long sum = 0;
for (byte k = 0; k < m1.ColCount; k )
{
sum = m1.GetElement(row, k) * m2.GetElement(k, j);
}
resultMatrix.SetElement(row, j, sum);
}
});
return resultMatrix;
}
但是回圈中的型別引數有錯誤。我該如何解決?
uj5u.com熱心網友回復:
只需使用 Parallel.For 而不是 Parallel.Foreach,這應該可以讓您保持與非并行版本完全相同的主體:
Parallel.For(0, m1.RowCount, i =>{
...
}
請注意,只有相當大的矩陣才能從并行化中受益,因此如果您正在使用 4x4 矩陣進行圖形處理,則不適合采用這種方法。
矩陣相乘的一個問題是,您需要為最內層回圈中的一個矩陣訪問每一行的一個值。這種訪問模式可能難以被您的處理器快取,從而導致大量快取未命中。因此,一個相當簡單的優化是將一整列復制到一個臨時陣列中,并在讀取下一列之前執行所有需要該列的計算。這讓所有的記憶體訪問都很好,線性且易于快取。這總體上會做更多的作業,但更好的快取利用率很容易使它成為勝利。還有更多快取有效的方法,但復雜性也趨于增加。
另一種優化是使用SIMD,但這可能需要特定于平臺的代碼才能獲得最佳性能,并且可能涉及更多作業。但是您也許能夠找到已經優化的庫。
但也許最重要的是,Profile your code。很容易讓簡單的事情消耗大量時間。例如,您正在使用介面,因此如果您可能對無法行內的每個記憶體訪問進行虛擬方法呼叫,與直接陣列訪問相比,可能會導致嚴重的性能損失。
uj5u.com熱心網友回復:
ForEach接收一個集合,IEnumerable作為第一個引數并且m1.RowCount是一個數字。大概Parallel.For()就是你想要的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/481891.html
上一篇:在c#中使用lock陳述句
