Hi folks,

While running rally in OpenStack we found out that ovn-northd was
at 100% CPU most of the time. It doesn't have to be necessarily
a problem but I wanted to do a simple profiling by running a rally task
which creates a network (Logical Switch) and creates 6 ports on it,
repeating the whole operation 1000 times. The ports are networks
are also deleted.

I used master branch and compiled it with -O1:

CFLAGS="-O1 -g" ./configure --prefix=/usr/local/
--with-linux=/usr/lib/modules/`ls /usr/lib/modules/ | tail -n 1`/build

gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)

What I saw is that ~ 15% of the execution time was spent in
uuid_from_string() function in util/uuid.c module which calls hexits_value()
which ends up calling hexit_value(). This last function gets called >1M
times.

I thought that it was worth to inline hexit_value() and use a lookup table
instead the switch/case [0] so I did it (find the patch below) and the gain
is
that instead of a 14%, uuid_from_string() now takes a 9% of the total
execution time. See [1].

[0]
https://github.com/openvswitch/ovs/blob/79feb3b0de83932c6cbf761d70051330db4d07f7/lib/util.c#L844
[1] https://imgur.com/a/3gzDF

Patch:
Note that we could make the table smaller to optimize the data cache usage
but then we would have to accommodate the argument and include extra
checks.


-------------------------------------------------------

diff --git a/lib/util.c b/lib/util.c
index a4d22df0c..a24472690 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -839,38 +839,6 @@ str_to_double(const char *s, double *d)
     }
 }

-/* Returns the value of 'c' as a hexadecimal digit. */
-int
-hexit_value(int c)
-{
-    switch (c) {
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-        return c - '0';
-
-    case 'a': case 'A':
-        return 0xa;
-
-    case 'b': case 'B':
-        return 0xb;
-
-    case 'c': case 'C':
-        return 0xc;
-
-    case 'd': case 'D':
-        return 0xd;
-
-    case 'e': case 'E':
-        return 0xe;
-
-    case 'f': case 'F':
-        return 0xf;
-
-    default:
-        return -1;
-    }
-}
-
 /* Returns the integer value of the 'n' hexadecimal digits starting at
's', or
  * UINTMAX_MAX if one of those "digits" is not really a hex digit.  Sets
'*ok'
  * to true if the conversion succeeds or to false if a non-hex digit is
diff --git a/lib/util.h b/lib/util.h
index b6639b8b8..f41e2a030 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -217,7 +217,28 @@ bool ovs_scan_len(const char *s, int *n, const char
*format, ...);

 bool str_to_double(const char *, double *);

-int hexit_value(int c);
+
+static const char hextable[] = {
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1, 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+};
+
+/* Returns the value of 'c' as a hexadecimal digit. */
+static inline int
+hexit_value(int c)
+{
+    return hextable[c & 0xff];
+}
+
 uintmax_t hexits_value(const char *s, size_t n, bool *ok);

 int parse_int_string(const char *s, uint8_t *valuep, int field_width,


-------------------------------------------------------
_______________________________________________
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss

Reply via email to