DPDK(10):報文處理中的指令預取(prefetcht0)

在DPDK的例子中報文處理時讀取報文內容時添加了指令預取命令(prefetcht0):

		/*
		 * Read packet from RX queues
		 */
		for (i = 0; i < qconf->n_rx_port; i++) {

			portid = qconf->rx_port_list[i];
			nb_rx = rte_eth_rx_burst((uint8_t) portid, 0,
						 pkts_burst, MAX_PKT_BURST);

			port_statistics[portid].rx += nb_rx;

			for (j = 0; j < nb_rx; j++) {
				m = pkts_burst[j];
				rte_prefetch0(rte_pktmbuf_mtod(m, void *));
				l2fwd_simple_forward(m, portid);
			}
		}

static inline void rte_prefetch0(volatile void *p)
{
	asm volatile ("prefetcht0 %[p]" : [p] "+m" (*(volatile char *)p));
}

這條指令主要的作用是人爲判斷下面將要處理的內存,指示CPU加載到緩存中,不過一般需要我們進行實測,向上面這種情況,性能肯定會有提升,一般可以提升10%。


下面是這一系列指令的介紹:轉自http://blog.csdn.net/igame/article/details/1752430

 
和緩存預取有關的指令:
操作碼          指令        Description
0F 18 /1        PREFETCHT0 m8   預取數據到所有級別的緩存,包括L0
0F 18 /2        PREFETCHT1 m8   預取數據到除L0外所有級別的緩存。
0F 18 /3        PREFETCHT2 m8   預取數據到除L0L1外所有級別的緩存。
0F 18 /0        PREFETCHNTA m8 預取數據到非臨時緩衝結構中,可以最小化對緩存的污染。
 
Intel® C++ Compiler的Intrinsic等效方法:
void _mm_prefetch(char *p, int i)
 從地址P處預取尺寸爲cache line大小的數據緩存,參數i指示預取方式(_MM_HINT_T0, _MM_HINT_T1, _MM_HINT_T2, _MM_HINT_NTA,分別表示不同的預取方式)
 
       如果在CPU操作數據之前,我們就已經將數據主動加載到緩存中,那麼就減少了由於緩存不命中,需要從內存取數的情況,這樣就可以加速操作,獲得性能上提升。使用主動緩存技術來優化內存拷貝,理論上應該能夠提高性能,看來值得一試。
 
注意,CPU對數據操作擁有絕對自由!使用預取指令只是按我們自己的想法對CPU的數據操作進行補充,有可能CPU當前並不需要我們加載到緩存的數據,這樣,我們的預取指令可能會帶來相反的結果,比如對於多任務系統,有可能我們沖掉了有用的緩存。不過,在多任務系統上,由於線程或進程的切換所花費的時間相對於預取操作來說太長了,簡直好象一個世紀,所以可以忽略線程或進程切換對緩存預取的影響。 

發佈了24 篇原創文章 · 獲贊 8 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章