rte_prefetch(报文处理中的指令预取)

Cache Miss的代价非常高,回内存读需要65纳秒,可以将即将访问的数据主动推送的CPU Cache进行优化。比较典型的场景是链表的遍历,链表的下一节点都是随机内存地址,所以CPU肯定是无法自动预加载的。但是我们在处理本节点时,可以通过CPU指令将下一个节点推送到Cache里。

操作码 指令 Description
0F 18 /1 PREFETCHT0 m8 预取数据到所有级别的缓存,包括 L0 。
0F 18 /2 PREFETCHT1 m8 预取数据到除 L0 外所有级别的缓存。
0F 18 /3 PREFETCHT2 m8 预取数据到除 L0 和 L1 外所有级别的缓存。
0F 18 /0 PREFETCHNTA m8 预取数据到非临时缓冲结构中,可以最小化对缓存的污染。

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

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

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

	/* Prefetch first packets */
	/* Configure how many packets ahead to prefetch, when reading packets 
	   #define PREFETCH_OFFSET 3*/
	for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) {
		rte_prefetch0(rte_pktmbuf_mtod(
				pkts_burst[j], void *));
	}

	/* Prefetch and forward already prefetched packets */
	for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
		rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
				j + PREFETCH_OFFSET], void *));
		l3fwd_simple_forward(pkts_burst[j], qconf, i, portid);
	}
}

CPU读取数据的效率为:

L1:3-5个时钟周期
L2:十几个时钟周期
L3:几十个时钟周期
内存:几百个时钟周期

cache的基本操作单位是cache line,如果一个cache line中包含两个不同的数据,那么如果一个线程对其中一个数据进行写操作,那么这个cache line就需要更新,意味着另一个线程需要重新加载另一个数据。所以两个不同的数据不要放在同一个cache line中,这就需要数据定义的时候声明cache对齐,例如cache line的大小是128位(16字节),定义一个8字节的long,剩下8字节使用无用的数据来填充。

DPDK中声明cache line对齐的关键字:__rte_cache_aligned

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值