1. 程式人生 > >DPDK(10):報文處理中的指令預取(prefetcht0)

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當前並不需要我們載入到快取的資料,這樣,我們的預取指令可能會帶來相反的結果,比如對於多工系統,有可能我們沖掉了有用的快取。不過,在多工系統上,由於執行緒或程序的切換所花費的時間相對於預取操作來說太長了,簡直好象一個世紀,所以可以忽略執行緒或程序切換對快取預取的影響。