存儲轉(zhuǎn)發(fā)是Intel Pentinum 4 和 pentinum6系列提供的一種加速讀寫指令執(zhí)行的技術(shù)。當處理器執(zhí)行一條存儲指令時,存儲緩沖區(qū)被分配。一旦存儲指令被執(zhí)行,存儲緩沖區(qū)含有存儲指令寫入內(nèi)存的數(shù)值和內(nèi)存地址。對于存儲之后發(fā)生的載入,在它們被執(zhí)行前經(jīng)常不必等候存儲指令的完成。如果載入來源于非重疊的內(nèi)存區(qū),載入指令可以不受存儲指令的影響而開始執(zhí)行。如果載入與存儲區(qū)域完全重疊,來自存儲的數(shù)值有時能夠直接傳給載入,不必等候完成寫數(shù)據(jù)到緩存的存儲。當存儲轉(zhuǎn)發(fā)的條件不滿足時,內(nèi)存的加載操作就會被延遲。當一個載入與存儲有部分重疊或全部重疊但沒有轉(zhuǎn)發(fā)時,載入必須等候存儲完成并且在載入執(zhí)行前完成寫存儲數(shù)據(jù)到緩存。有時,載入或存儲地址的生成延遲能夠引起處理器認為載入與存儲間有重疊。這些存儲轉(zhuǎn)發(fā)問題能夠引起嚴重的性能問題,因而應當避免。
舉個例子,在圖像應用中,一段處理32位RGBA顏色值的代碼可能遇到這樣的問題:產(chǎn)生一個新的紅色值,并把這個8位的值存到一個內(nèi)存地址,然后讀回整個32位值。當存一個字節(jié)數(shù)較少的數(shù)值,然后取回一個包含這個數(shù)值的字節(jié)數(shù)更多的操作數(shù)時,處理器的存儲-轉(zhuǎn)發(fā)操作將會被中斷。這是因為被加載的部分數(shù)據(jù)可能位于內(nèi)存系統(tǒng)(Cache,DRAM)的其他地方。
為了避免上述的情況導致的內(nèi)存延遲,可以32位整形為單位處理所有4個顏色值,然后把這32位整形一起寫道內(nèi)存中。為了利用處理器的存儲轉(zhuǎn)發(fā)功能,一個讀操作加載的數(shù)據(jù)的尺寸必須等于或小于先前寫操作的數(shù)據(jù),并且保證讀寫操作的起始地址是相同的。
改進應用的內(nèi)存訪問模式,避免對存儲轉(zhuǎn)發(fā)的限制,可以獲得顯著的性能改進,使用Intel編譯器(5.0以后的版本)或微軟VisualC編譯器(7.0以后的版本)可以消除很多存儲-轉(zhuǎn)發(fā)沖突的情況。但是編譯器經(jīng)常不會知道存儲轉(zhuǎn)發(fā)問題是否存在。在Pentium4處理器上使用MOB Loads Replays Retired事件,在Pentium M處理器上使用Resource RelatedStalls事件,使用這些VTune事件可以更容易地發(fā)現(xiàn)存儲轉(zhuǎn)發(fā)的問題。需要注意的是:在PentiumM處理器上,VTune分析器的計數(shù)器Resource RelatedStalls不只對存儲轉(zhuǎn)發(fā)事件進行計數(shù)。如果你看到這個事件經(jīng)常發(fā)生,在附近的指令中查找存儲轉(zhuǎn)發(fā)的問題。如果沒有發(fā)現(xiàn)這個問題,該事件也能由其它資源相關(guān)的問題引起,如用盡載入和存儲緩沖區(qū),或者簡單地執(zhí)行機器一次能夠處理的最大數(shù)目的微操作。