This optimization is done to avoid calling count_1bits(), which, if the popcnt istruction, is not available might is slow. popcnt may not be available because:
- We are running on old hardware - (more likely) We're using a generic build (i.e. packaged OVS from a distro), not tuned for the specific CPU Signed-off-by: Daniele Di Proietto <ddiproie...@vmware.com> --- This commit improves 1-flow UDP 64-bytes packets test throughput by 6% (compiled without -march=native) --- lib/dpif-netdev.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 112cd5a..ea14838 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -129,6 +129,7 @@ struct netdev_flow_key { struct emc_entry { uint32_t hash; + uint32_t mf_len; struct netdev_flow_key mf; struct dp_netdev_flow *flow; }; @@ -398,6 +399,7 @@ emc_cache_init(struct emc_cache *flow_cache) for (i = 0; i < ARRAY_SIZE(flow_cache->entries); i++) { flow_cache->entries[i].flow = NULL; flow_cache->entries[i].hash = 0; + flow_cache->entries[i].mf_len = 0; miniflow_initialize(&flow_cache->entries[i].mf.flow, flow_cache->entries[i].mf.buf); } @@ -1171,11 +1173,10 @@ netdev_flow_key_size(uint32_t flow_u32s) /* Used to compare 'netdev_flow_key's (miniflows) in the exact match cache. */ static inline bool netdev_flow_key_equal(const struct netdev_flow_key *a, - const struct netdev_flow_key *b) + const struct netdev_flow_key *b, + uint32_t size) { - uint32_t size = count_1bits(a->flow.map); - - return !memcmp(a, b, netdev_flow_key_size(size)); + return !memcmp(a, b, size); } static inline void @@ -1183,7 +1184,7 @@ netdev_flow_key_clone(struct netdev_flow_key *dst, const struct netdev_flow_key *src, uint32_t size) { - memcpy(dst, src, netdev_flow_key_size(size)); + memcpy(dst, src, size); } static inline bool @@ -1217,8 +1218,11 @@ emc_change_entry(struct emc_entry *ce, struct dp_netdev_flow *flow, } } if (mf) { - netdev_flow_key_clone(&ce->mf, mf, count_1bits(mf->flow.map)); + uint32_t mf_len = netdev_flow_key_size(count_1bits(mf->flow.map)); + + netdev_flow_key_clone(&ce->mf, mf, mf_len); ce->hash = hash; + ce->mf_len = mf_len; } } @@ -1232,7 +1236,8 @@ emc_insert(struct emc_cache *cache, const struct miniflow *mf, uint32_t hash, EMC_FOR_EACH_POS_WITH_HASH(cache, current_entry, hash) { if (current_entry->hash == hash && netdev_flow_key_equal(¤t_entry->mf, - miniflow_to_netdev_flow_key(mf))) { + miniflow_to_netdev_flow_key(mf), + current_entry->mf_len)) { /* We found the entry with the 'mf' miniflow */ emc_change_entry(current_entry, flow, NULL, 0); @@ -1263,7 +1268,8 @@ emc_lookup(struct emc_cache *cache, const struct miniflow *mf, uint32_t hash) EMC_FOR_EACH_POS_WITH_HASH(cache, current_entry, hash) { if (current_entry->hash == hash && emc_entry_alive(current_entry) && netdev_flow_key_equal(¤t_entry->mf, - miniflow_to_netdev_flow_key(mf))) { + miniflow_to_netdev_flow_key(mf), + current_entry->mf_len)) { /* We found the entry with the 'mf' miniflow */ return current_entry->flow; -- 2.1.0.rc1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev