简介
简单来说,为了加速CPU访问内存的速度,于是有了访问更快的缓存结构,一般包括L1、L2、L3。
示例
通常在进行数据包处理时会先对数据包进行预取操作,dpdk中触发CPU预取的指令如下:
- rte_prefetch0 预取数据到所有级别的缓存
- rte_prefetch1 预取数据到所有级别的缓存,除L0外。
- rte_prefetch2 预取数据到所有级别的缓存,除L0和L1外。
- rte_prefetch_non_temporal 预取数据到非临时性的缓存,即只将数据预取到较低级别的缓存中,比如L2或L3缓存。这可以防止预取数据污染顶级缓存。
以下为dpdk中ipv4_multicast示例代码,采用的是rte_prefetch0,考虑缓存大小不一次全部预取(防止预取数据污染)。
- 首先循环预取PREFETCH_OFFSET三个数据包到所有级别缓存。
- 再循环预取一个新的数据包,同时处理一个已经预取的数据包。
- 最后循环处理剩下预取的数据包。
while (1) {
/*
* Read packet from RX queues
*/
for (i = 0; i < qconf->n_rx_queue; i++) {
portid = qconf->rx_queue_list[i];
nb_rx = rte_eth_rx_burst(portid, 0, pkts_burst,
MAX_PKT_BURST);
/* Prefetch first packets */
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 *));
mcast_forward(pkts_burst[j], qconf);
}
/* Forward remaining prefetched packets */
for (; j < nb_rx; j++) {
mcast_forward(pkts_burst[j], qconf);
}
}
/* Send out packets from TX queues */
send_timeout_burst(qconf);
}