curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Improve cpu utilization

From: Daniel Stenberg via curl-library <>
Date: Thu, 25 Mar 2021 22:55:30 +0100 (CET)

On Thu, 25 Mar 2021, Nikos Dragazis via curl-library wrote:

> and we have seen that 1/4 of the overall cpu utilization comes from
> libcurl's `poll(2)` system calls. Specifically, the code paths to blame
> are:
> * `easy_transfer()` -> `curl_multi_poll()` -> `multi_wait()` -> `Curl_poll()`
> * `Curl_readwrite()` -> `Curl_socket_check()` -> `Curl_poll()`

That second Curl_poll() at least should be possible to get rid of. Possibly
more when it loops?

> 1. Remove `poll(2)` system calls from the critical path, that is from
>    `easy_transfer()` and `Curl_readwrite()`.
> 2. Make connection sockets blocking instead of non-blocking.

It is important for libcurl's internals that it never blocks on any socket. It
is supposed to be able to deal with N connections and transfers in parallel
and that requires non-blocking.

For a limited and special use-case you can most probably work fine without
non-blocking sockets, but it will hurt others.

> 3. Force `Curl_readwrite()` to ignore `KEEP_RECV` if `KEEP_SEND` is set.

That's another and much harder no-can-do. libcurl must handle transfers in
both directions simultaneously. Not doing so will lead to serious problem in
some use cases.

> That said, we believe that it would make sense to introduce ablocking
> mode/feature in libcurl with no polling in the critical pathfor
> performance reasons.

I think that's a premature conclusion. I think a first round should make sure
that there are no superfluous calls to poll when such can and should be

When that is achieved, we can measure again and discuss what the next step
should be.

Finally: poll() is slow when doing many transfers - there's not a lot we can
do about that. The more connections, the slower. We introduced the
multi_socket() API many years ago to make it possible to completely avoid
poll() or select() and instead use event-based APIs. To really be able to
maximize libcurl's CPU performance, you probably need to use that API.

  | Commercial curl support up to 24x7 is available!
  | Private help, bug fixes, support, ports, new features

Received on 2021-03-25