From 5963a0384f1317d03f65247e96a82bef402b0be0 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 28 Sep 2016 14:57:43 +0300 Subject: performance tweak - faster checksum --- linux/ws_main.py | 2 +- src/common/Network/Packet/IPHeader.h | 57 ++++++++++++++++++++++++++++++++++++ src/stateless/cp/trex_stream_vm.h | 9 +++--- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/linux/ws_main.py b/linux/ws_main.py index b843fcb5..a140e174 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -347,7 +347,7 @@ class build_option: result+=['-m32']; if self.isRelease () : - result+=['-O2']; + result+=['-O3']; else: result+=['-O0','-DDEBUG','-D_DEBUG','-DSTILE_CPP_ASSERT','-DSTILE_SHIM_ASSERT']; diff --git a/src/common/Network/Packet/IPHeader.h b/src/common/Network/Packet/IPHeader.h index b9ef8a2e..dd9f5096 100755 --- a/src/common/Network/Packet/IPHeader.h +++ b/src/common/Network/Packet/IPHeader.h @@ -19,6 +19,10 @@ limitations under the License. #include "PacketHeaderBase.h" +#ifndef likely +#define likely(x) __builtin_expect((x),1) +#endif /* likely */ + #define IPV4_HDR_LEN 20 class IPHeader @@ -140,6 +144,59 @@ public: inline void swapSrcDest (); + + inline void updateCheckSumFast() { + myChecksum = 0; + + if (likely(myVer_HeaderLength == 0x45)) { + myChecksum = calc_cksum_fixed(); + } else { + myChecksum = calc_cksum_nonfixed(); + } + + } + +protected: + + /* fast inline checksum calculation */ + inline uint16_t calc_cksum_fixed() { + const uint16_t *ipv4 = (const uint16_t *)this; + + int sum = 0; + + /* calcualte 20 bytes unrolled loop */ + sum += ipv4[0]; + sum += ipv4[1]; + sum += ipv4[2]; + sum += ipv4[3]; + sum += ipv4[4]; + sum += ipv4[5]; + sum += ipv4[6]; + sum += ipv4[7]; + sum += ipv4[8]; + sum += ipv4[9]; + + sum = (sum & 0xffff) + (sum >> 16); + + return (uint16_t)(~sum); + } + + /* a slow non-frequent call - never inline */ + uint16_t calc_cksum_nonfixed() __attribute__ ((noinline)) { + const uint16_t *ipv4 = (const uint16_t *)this; + + int sum = 0; + int hlen = getHeaderLength(); + + for (int i = 0; i < (hlen / 2); i++) { + sum += ipv4[i]; + } + + sum = (sum & 0xffff) + (sum >> 16); + + return (uint16_t)(~sum); + } + //////////////////////////////////////////////////////////////////////////////////////// // Common Header Interface //////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index be0c03ba..a0de7b2e 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -499,16 +499,15 @@ public: } __attribute__((packed)); - - struct StreamDPOpIpv4Fix { uint8_t m_op; uint16_t m_offset; public: void dump(FILE *fd,std::string opt); - void run(uint8_t * pkt_base){ - IPHeader * ipv4= (IPHeader *)(pkt_base+m_offset); - ipv4->updateCheckSum(); + void run(uint8_t * pkt_base) { + + IPHeader *ipv4 = (IPHeader *)(pkt_base+m_offset); + ipv4->updateCheckSumFast(); } } __attribute__((packed)); -- cgit 1.2.3-korg