src/liboping.c: Performance improvements.
authorLuke Heberling <collectd@c-ware.com>
Sat, 6 Aug 2016 12:46:30 +0000 (14:46 +0200)
committerFlorian Forster <ff@octo.it>
Sat, 6 Aug 2016 12:46:30 +0000 (14:46 +0200)
commitd717d41928fab9354e88d91ef1996151565012d8
tree987c2dc2b244a76b51a067f33221671acfc492e7
parent207d51d66b383b501c15cacd6a24d7013c8c6a1d
src/liboping.c: Performance improvements.

I'm finding collectd's ping plugin inadequate for host lists larger than
a few hundred. It consumes an entire 2.8Ghz CPU and reports random false
packet loss (Latest collectd and liboping from git.verplant.org on
debian squeeze and lenny). This seems to be because of some
inefficiencies in liboping. For instance, a FD is created for every
host. Since each raw socket receives all raw packets, only one FD would
be needed for all hosts (of the same addrfamily). Besides consuming all
those additional FD's, each reply packet is received and processed
separately on each FD causing O(n^2) complexity. Also for each packet
processed on each FD, a scan of all hosts is performed causing O(n^3).

So, I implemented some new features for liboping:
   * use icmp ident as "hash" for table lookup on RX
   * allocate one socket FD per addressfamily (not per host)
   * multiplex socket writes in the same select loop as reads
      * This was necessary because sometimes the first reply
         is received before last request is sent.

It's working well for me in testing so far. 1-3% CPU with 1000 hosts,
compared to 100% and useless at 500 hosts before these changes. If
there's interest I'll update this thread with any significant changes.
As always, changes to address style/portability/other issues that
inhibit integration upstream will be my pleasure.
src/liboping.c