Optimized the performance of updating the statistics counters by reducing the number of branches.
Ordered the packet size comparisons according to the probability with typical internet traffic mix. Signed-off-by: Morten Brørup <m...@smartsharesystems.com> --- lib/vhost/virtio_net.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c index 370402d849..25a495df56 100644 --- a/lib/vhost/virtio_net.c +++ b/lib/vhost/virtio_net.c @@ -53,7 +53,7 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring) } static inline void -vhost_queue_stats_update(struct virtio_net *dev, struct vhost_virtqueue *vq, +vhost_queue_stats_update(const struct virtio_net *dev, struct vhost_virtqueue *vq, struct rte_mbuf **pkts, uint16_t count) __rte_shared_locks_required(&vq->access_lock) { @@ -64,37 +64,25 @@ vhost_queue_stats_update(struct virtio_net *dev, struct vhost_virtqueue *vq, return; for (i = 0; i < count; i++) { - struct rte_ether_addr *ea; - struct rte_mbuf *pkt = pkts[i]; + const struct rte_ether_addr *ea; + const struct rte_mbuf *pkt = pkts[i]; uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt); stats->packets++; stats->bytes += pkt_len; - if (pkt_len == 64) { - stats->size_bins[1]++; - } else if (pkt_len > 64 && pkt_len < 1024) { - uint32_t bin; - - /* count zeros, and offset into correct bin */ - bin = (sizeof(pkt_len) * 8) - rte_clz32(pkt_len) - 5; - stats->size_bins[bin]++; - } else { - if (pkt_len < 64) - stats->size_bins[0]++; - else if (pkt_len < 1519) - stats->size_bins[6]++; - else - stats->size_bins[7]++; - } + if (pkt_len >= 1024) + stats->size_bins[6 + (pkt_len > 1518)]++; + else if (pkt_len <= 64) + stats->size_bins[pkt_len >> 6]++; + else + stats->size_bins[32UL - rte_clz32(pkt_len) - 5]++; - ea = rte_pktmbuf_mtod(pkt, struct rte_ether_addr *); - if (rte_is_multicast_ether_addr(ea)) { - if (rte_is_broadcast_ether_addr(ea)) - stats->broadcast++; - else - stats->multicast++; - } + ea = rte_pktmbuf_mtod(pkt, const struct rte_ether_addr *); + RTE_BUILD_BUG_ON(offsetof(struct virtqueue_stats, broadcast) != + offsetof(struct virtqueue_stats, multicast) + sizeof(uint64_t)); + if (unlikely(rte_is_multicast_ether_addr(ea))) + (&stats->multicast)[rte_is_broadcast_ether_addr(ea)]++; } } -- 2.43.0