2009-07-02 75 views
1

以下函數針對T運行兩個值。一個是4個字節(與DWORD相同)。另一個是64字節。緩衝區旨在將對象存儲在其緩存中,並在稍後的日期檢索它們。C++ STD :: Vector使用模板化函數需要異常長時間運行

當使用64字節結構時,函數中的總時間會顯着跳躍。向量中的查找時間,memcpy甚至在函數的「SELF」部分中的時間都急劇增加。

存儲函數幾乎與下面的代碼相反,並且似乎沒有遭受相同的不對稱時間。

任何想法爲什麼?

template <class T> 
void Buffer::retrieve (T& Value) 
    { 
    int nTypeSize = sizeof (T); 
    int nDWORDSize = sizeof (DWORD); 

    /* 
    * Number of DWORDs needed to store this value. 
    */ 

    int nDWORDCount = (nTypeSize + 3)/4; 

    if (m_nReadPosition + nDWORDCount >= m_nSize) 
     return; 

    memcpy (&Value, &m_Cache[m_nReadPosition], nTypeSize); //m_Cache is a DWORD vector. 
    m_nReadPosition += nDWORDCount; 
    } 
+5

首先,你使用的是什麼系統?第二,你的意思是什麼?我希望事情需要更長的時間,比64字節多4字節。第三,你是什麼意思「尋找向量中的時間」和「功能」的「自我」部分?第四,你如何確定時間? – 2009-07-02 15:54:27

+0

除了一些進一步的e xplanations按其他人的要求,你應該注意到,發佈的解決方案是脆弱的,它不適用於依賴於用戶提供的拷貝構造函數的T類型(資源處理對象) – 2009-07-02 16:31:46

+0

什麼,它是16倍慢?給我們一個號碼!我不會感到驚訝,如果它稍微超過這個數量,那麼當複製64字節時,可能不會執行memcpy()的一些編譯器優化。 – 2009-07-02 21:24:01

回答

1

的memcpy的時間增加可能只是降低到複製多個字節作爲時間的memcpy將縮放(天真地)與存儲器的量被複制。這不一定是線性縮放,因爲memcpy的某些實現將通過一次複製32位或64位來優化。

在STD中的查找::載體不應當與對象尺寸既不m_nReadPosition或m_Cache被縮放取決於T.

你將有一些慢下來操縱Ť雖然作爲4任何代碼字節結構可以存儲在32位處理器的寄存器中,而編譯器要處理的任何東西都會更復雜。這可能會增加一些開銷。

總時間增加多少?如果它是16的倍數,我完全把它放在T的大小變化上。

0

我會懷疑分析器的歸屬時間來自這裏調用的函數:std::vector的訪問器是一個內聯,並且memcpy()可能是一個編譯器內在的,這意味着在一個優化的版本構建中(您的定時發佈版本,對不對?),他們的大部分工作將歸因於調用函數。

因此,我會運行一些對照實驗來定位減速。例如,對於散裝的CPU時間在這裏最有可能的罪魁禍首是memcpy(),所以儘量把它的方程暫時的:

volatile DWORD g_dummy; 
void Buffer::retrieve (T& Value) 
    { 
    /* ... */ 
    // memcpy (&Value, &m_Cache[m_nReadPosition], nTypeSize); 
    g_dummy += m_Cache[m_nReadPosition]; // force the compiler to perform the vector lookup 
    m_nReadPosition += nDWORDCount; 
    } 

,看看有多少是真的複製佔放緩。

1

如果您有std::vector,爲什麼使用memcpy?我會推薦使用std::copystd::vector的自己的方法。這在很大程度上是一種風格上的改變,但它確實保證了構造函數被調用。

至於爲什麼事情會慢,我不知道:

  • 在載體中的尋道時間,

這很奇怪,因爲向量點連續的內存,並且尋找內存的時間是不變的。也就是說,如果我指向矢量中的第一個項目,那麼從第二個項目移動到最後一個項目需要花費很多時間(通過+,+=std::advance)。

如果您使用的是std::list,則會顯示尋找時間。但它不應該成爲矢量。並且它絕對不應該在矢量的原始存儲器上運行的memcpy中。

  • 的memcpy的

你複製16倍的數據(4個字節,與64個字節)。

  • ,甚至時間的函數的「自我」部分的所有顯着上升。

這也是奇數,如

int nTypeSize = sizeof (T); 
int nDWORDSize = sizeof (DWORD); 
int nDWORDCount = (nTypeSize + 3)/4; 

都編譯時間常數和應該由編譯器對於每種類型T.預先計算

if (m_nReadPosition + nDWORDCount >= m_nSize) 

m_nReadPosition += nDWORDCount; 

are th僅在Buffer::retrieve中實際在運行時執行的行(除memcpy之外)。除非這種增長僅僅是由於重複計算的memcpy(一旦標題爲「memcpy」下,一旦標題下的「Buffer::retrieve。」


事情需要提防的std::vector是零碎的內存分配和不必要的但是你在示例代碼中沒有做任何事情

相關問題