Performance improvements: 21/521/1
authorJason Ye <yisye@cisco.com>
Wed, 26 Jun 2013 06:24:00 +0000 (23:24 -0700)
committerJason Ye <yisye@cisco.com>
Wed, 26 Jun 2013 06:24:00 +0000 (23:24 -0700)
Solution: Use LinkedBlockingQueue with fixed capacity. The MAXQUEUESIZE is now set to 50,000. With the change, the system become stable.

Solution: Implemented more efficient way to compute header checksum. As a result, the throughout has more than doubled.See test results below. Used Cbench for testing.

Before:
RESULT: 16 switches 9 tests min/max/avg/stdev =
9598.35/10395.48/10193.23/225.24 responses/s

After:
RESULT: 16 switches 9 tests min/max/avg/stdev =
28767.44/32073.92/30335.74/999.70 responses/s

Solution: Transmit messages in a tight while loop until the Tx queue is empty.

Signed-off-by: Jason Ye <yisye@cisco.com>
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/Controller.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SwitchHandler.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java

index 7fb5f9fcf134c2b83a4d6534dca9356af206103b..40f594bd2a0e12bfe13215fb50672909fe5de856 100644 (file)
@@ -50,6 +50,7 @@ public class Controller implements IController, CommandProvider {
     // only 1 switch state listener
     private ISwitchStateListener switchStateListener;
     private AtomicInteger switchInstanceNumber;
     // only 1 switch state listener
     private ISwitchStateListener switchStateListener;
     private AtomicInteger switchInstanceNumber;
+    private int MAXQUEUESIZE = 50000;
 
     /*
      * this thread monitors the switchEvents queue for new incoming events from
 
     /*
      * this thread monitors the switchEvents queue for new incoming events from
@@ -112,7 +113,7 @@ public class Controller implements IController, CommandProvider {
     public void init() {
         logger.debug("Initializing!");
         this.switches = new ConcurrentHashMap<Long, ISwitch>();
     public void init() {
         logger.debug("Initializing!");
         this.switches = new ConcurrentHashMap<Long, ISwitch>();
-        this.switchEvents = new LinkedBlockingQueue<SwitchEvent>();
+        this.switchEvents = new LinkedBlockingQueue<SwitchEvent>(MAXQUEUESIZE);
         this.messageListeners = new ConcurrentHashMap<OFType, IMessageListener>();
         this.switchStateListener = null;
         this.switchInstanceNumber = new AtomicInteger(0);
         this.messageListeners = new ConcurrentHashMap<OFType, IMessageListener>();
         this.switchStateListener = null;
         this.switchInstanceNumber = new AtomicInteger(0);
index 5d51d26a988f553f0e79a3d2a29b408ddb486871..81729c3dec029b39502562fdb0dc2c0cfd35ce8f 100644 (file)
@@ -771,7 +771,7 @@ public class SwitchHandler implements ISwitch {
             running = true;
             while (running) {
                 try {
             running = true;
             while (running) {
                 try {
-                    if (!transmitQ.isEmpty()) {
+                    while (!transmitQ.isEmpty()) {
                         PriorityMessage pmsg = transmitQ.poll();
                         msgReadWriteService.asyncSend(pmsg.msg);
                         logger.trace("Message sent: {}", pmsg);
                         PriorityMessage pmsg = transmitQ.poll();
                         msgReadWriteService.asyncSend(pmsg.msg);
                         logger.trace("Message sent: {}", pmsg);
index 9bdb5d084c57b7fede9fe1557a4934ae31e981e4..5075e58281132a4404ab8473be01e05ea5305115 100644 (file)
@@ -146,6 +146,7 @@ public class ICMP extends Packet {
      */
     short computeChecksum(byte[] data, int start) {
         int sum = 0, carry = 0, finalSum = 0;
      */
     short computeChecksum(byte[] data, int start) {
         int sum = 0, carry = 0, finalSum = 0;
+        int wordData;
         int end = start + this.getHeaderSize() / NetUtils.NumBitsInAByte
                 + rawPayload.length;
         int checksumStartByte = start + getfieldOffset(CHECKSUM)
         int end = start + this.getHeaderSize() / NetUtils.NumBitsInAByte
                 + rawPayload.length;
         int checksumStartByte = start + getfieldOffset(CHECKSUM)
@@ -156,12 +157,8 @@ public class ICMP extends Packet {
             if (i == checksumStartByte) {
                 continue;
             }
             if (i == checksumStartByte) {
                 continue;
             }
-            StringBuffer sbuffer = new StringBuffer();
-            sbuffer.append(String.format("%02X", data[i]));
-            if (i < (data.length - 1)) {
-                sbuffer.append(String.format("%02X", data[i + 1]));
-            }
-            sum += Integer.valueOf(sbuffer.toString(), 16);
+            wordData = ((data[i] << 8) & 0xFF00) + (data[i + 1] & 0xFF);
+            sum = sum + wordData;
         }
         carry = (sum >> 16) & 0xFF;
         finalSum = (sum & 0xFFFF) + carry;
         }
         carry = (sum >> 16) & 0xFF;
         finalSum = (sum & 0xFFFF) + carry;
index 7a7a5a757fb4ab4ff7184da84a25662f42729e07..1e2f4277c1f4035b873c61502a43bdc1e6d6fe4c 100644 (file)
@@ -455,7 +455,7 @@ public class IPv4 extends Packet {
         int end = start + getHeaderLen();
         short checkSum = (short) 0;
         int sum = 0, carry = 0, finalSum = 0;
         int end = start + getHeaderLen();
         short checkSum = (short) 0;
         int sum = 0, carry = 0, finalSum = 0;
-        int parsedHex = 0;
+        int wordData;
         int checksumStart = start
                 + (getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte);
 
         int checksumStart = start
                 + (getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte);
 
@@ -464,14 +464,8 @@ public class IPv4 extends Packet {
             if (i == checksumStart) {
                 continue;
             }
             if (i == checksumStart) {
                 continue;
             }
-            StringBuffer sbuffer = new StringBuffer();
-            sbuffer.append(String.format("%02X", data[i]));
-            if (i < (data.length - 1)) {
-                sbuffer.append(String.format("%02X", data[i + 1]));
-            }
-
-            parsedHex = Integer.valueOf(sbuffer.toString(), 16);
-            sum += parsedHex;
+            wordData = ((data[i] << 8) & 0xFF00) + (data[i + 1] & 0xFF);
+            sum = sum + wordData;
         }
         carry = (sum >> 16) & 0xFF;
         finalSum = (sum & 0xFFFF) + carry;
         }
         carry = (sum >> 16) & 0xFF;
         finalSum = (sum & 0xFFFF) + carry;