我有一個兩階段過程,在我的模擬程序中構成一個循環。更多或更少,我有以下:對STL向量執行重複操作是否允許「固有並行性」/改進的內存訪問?
struct Coordinates
{
double * x, * y, * z;
uint * kind, count;
double GetDist(const uint p1, const uint p2);
};
struct Polynomial
{
double * A, * B;
uint n1, n2;
uint Flatten(const uint i, const uint j);
double CalcResult(double distSq, uint kind1, uint kind2)
{
uint ij = Flatten(kind1, kind2);
double base = B * distSq;
return A[ij]*(pow(base,n2)-pow(base,n1));
}
};
我的問題是,如果我寫我的代碼就像
struct Model
{
Coordinates c;
Polynomial f;
double DoTest()
{
double result = 0;
uint count = 0;
std::vector<double> distSq;
for (uint i=0; i<c.count; i++)
{
for (uint j=i; j<c.count; j++)
{
result = c.GetDist(i,j);
distSq.push_back(result);
}
}
result = 0;
for (uint i=0; i<c.count; i++)
{
for (uint j=i; j<c.count; j++)
{
result += f.CalcResult(distSq[count], i, j);
count++;
}
}
return result;
}
double DoTest2()
{
double result = 0;
for (uint i=0; i<c.count; i++)
for (uint j=i; j<c.count; j++)
result += f.CalcResult(c.GetDist(i,j), i, j);
return result;
}
}
威爾Test
自動啓用並行性(如矢量數學或改進了內存訪問)的x86芯片,給出它在單個數據集上的重複操作?
否則Test
是一種垃圾方法 - 它使用額外的存儲空間(std::vector<double> distSq;
),並且在代碼讀取方面更長。從邏輯上講它是或多或少相同,但如果我們調用GetDist
f_A
(功能A)和CalcResult
f_B
(函數B),測試是:
f_A f_A f_A ... f_A f_B f_B .... f_B
凡爲短/更少的內存密集型功能
f_A f_B f_A f_B .... f_A f_B
我聽說過-O#
編譯的C代碼中所謂的「固有並行性」,這是由於生成的向量化數學運算等原因造成的。可能Test
在x86上啓用了這種編譯器派生的並行性(例如向量化數學或優化內存訪問?)芯片,給它的對單個數據集重複操作?
(否則Test2
是唯一合理的方法,因爲它使用更少的內存。)
而且將替換c樣式x
,y
和z
陣列與std::vector<double>
替代有加速計算或存儲器訪問的可能性以任何方式?
請不要回答「你自己的基準」...我想要通過基於編譯器的「理論基準」來測試方法Test
以獲得更好的理解,固有平行度「。
MSalters,它們是相同的,其實。這就是爲什麼我開始內循環@ j ---這是對唯一座標對的計算,所以我們只計算N×N座標空間的一半......關於內存訪問的好想法,謝謝......這就是我的想法...我可能會從f_A f_B開始...方法 –
正確,忽略了那一點 - 在這種情況下,您只需要預留(N * N + N)/ 2個元素。仍然是O(N * N)內存訪問。 – MSalters