Little benchmark of the CommonAPI example on a Raspberry Pi 2
CommonAPI [1] is an open-source (Mozilla Public License 2.0) developped by BMW.
It enables to abstract communication middleware (i.e., IPC) such as D-Bus [2] or SOME/IP [3].
Little benchmark for E01HelloWorld
The E01HelloWorld tutorial is found in the user guide [4].
commonapi.ini configuration:
[default] binding=someip [logging] console = true dlt = false level = verbose
Results for 10,000 requests:
1st try 2nd try 3rd try no logging 7.17268s 7.01405s 7.11199s print to console 10.1618s 9.34912s 9.47056s
Logging with GDB
First, let's do the same benchmark, with the client running inside gdb:
(running inside gdb) 1st try 2nd try 3rd try no logging 7.53790s 7.08302s 6.87121s print to console 9.30453s 9.80104s 9.92076s
By analyzing the source code of SOME/IP, one finds this method in routing_manager_proxy.hpp quite interesting:
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
We make a symbol dump of the SOME/IP shared library:
readelf -s --wide $SOMEIP_PATH/lib/libvsomeip.so > readelf_libvsomeip.dump
If the library was not stripped from all its local symbols (with strip --strip-all libvsomeip.so), this symbol will be found among many others:
cat readelf_libvsomeip.dump | grep "on_message" _ZThn4_N7vsomeip21routing_manager_proxy10on_messageEPKhjPNS_8endpointE
Let's set a breakpoint there and see the content of the arguments:
(gdb) b _ZThn4_N7vsomeip21routing_manager_proxy10on_messageEPKhjPNS_8endpointE
...and run the client (libvsomeip.so has debug symbols here):
Breakpoint 1, vsomeip::routing_manager_proxy::on_message (this=0x2d714, _data=0x756085ec "\027w\022$", _size=47, _receiver=0x2fa08) at /home/pi/capi/10_someip/vSomeIP/implementation/routing/src/routing_manager_proxy.cpp:515 515 endpoint *_receiver) {
The breakpoint was met and the content of the arguments is shown. Using _data and _size, we can display the content of the message:
(gdb) x/47xb 0x756085ec 0x756085ec: 0x17 0x77 0x12 0x24 0x00 0x00 0x00 0x12 0x756085f4: 0x34 0x80 0xe8 0x00 0x00 0x00 0x1c 0x11 0x756085fc: 0x2e 0x00 0x01 0x01 0x00 0x80 0x00 0x00 0x75608604: 0x00 0x00 0x10 0xef 0xbb 0xbf 0x48 0x65 0x7560860c: 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x75608614: 0x64 0x21 0x00 0x78 0x56 0x01 0x01
As expected, it contains a special sequence of ASCII characters (starting in the 4th line above):
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x21 H e l l o W o r l d !
With the correct offest, the data can be displayed as a simple null-terminated string:
(gdb) x/s (0x756085ec+30) 0x7560860a: "Hello World!"
Automatic breakpoint with GDB
The breapoint of the previous section can be automatized:
(gdb) set pagination off (gdb) b _ZThn4_N7vsomeip21routing_manager_proxy10on_messageEPKhjPNS_8endpointE (gdb) commands Type commands for breakpoint(s) 1, one per line. End with a line saying just "end". >silent >x/s $r1+30 >cont >end
gdb will break on each message, print the content of the message with the offset calculated earlier, and continue the execution.
How fast is it for 10,000 requests?
(running inside gdb) 1st try 2nd try 3rd try gdb auto. break 65.3633s 65.3735s 64.9654s
The execution is awfully slow, but there is a bonus: messages can be changed on the fly.
If we add a memory-set in the commands of the breakpoint, the client will see a different message each time:
(gdb) commands Type commands for breakpoint(s) 1, one per line. End with a line saying just "end". >silent >x/s $r1+30 >set {char}($r1+31) = 0x61 >cont >end
Result in gdb:
0x7560860a: "Hello World!" <- gdb break Got message: 'Hallo World!' <- console print from the client
References
[1] | IPC CommonAPI C++ project, http://projects.genivi.org/commonapi/home |
[2] | D-Bus project, https://www.freedesktop.org/wiki/Software/dbus |
[3] | SOME/IP project, http://some-ip.com |
[4] | CommonAPI User Guide, http://docs.projects.genivi.org/ipc.common-api-tools/3.1.3/html/CommonAPICppUserGuide.html |