c++linuxfolly

folly IOThreadPoolExecutor vs CPUThreadPoolExecutor


I'm trying to learn more about the async abstractions used by this codebase I'm working on.

I'm reading Folly's documentation for two async executor pools in the library, IOThreadPoolExecutor for io bound tasks, and CPUThreadPoolExecutor for cpu bound tasks (https://github.com/facebook/folly/blob/master/folly/docs/Executors.md).

I'm reading through the descriptions but I don't understand the main difference. It seems like IOThreadPoolExecutor is built around event_fd and epoll loop and CPUThreadPoolExecutor uses a queue and semaphore.

But that doesn't tell me that much about the benefits and trade-offs.


Solution

  • At a high level IPThreadPoolExecutors should be used only if you need a pool of EventBases. If you need a pool of workers, then use CPUThreadPoolExecutor.

    CPUThreadPoolExecutor

    Contains a series of priority queues which get constantly picked up by a series of workers. Each worker thread executes threadRun() after created. ThreadRun() is essentially an infinite loop which pulls one task from task queue and executes it. If the task is already expired when it is fetched, then the expire callback is executed instead of the task itself.

    cputhreadpoolexecutor

    IOThreadPoolExecutor

    Each IO thread runs its own EventBase. Instead of pulling task from task queue like the CPUThreadPoolExecutor, the IOThreadPoolExecutor registers an event to the EventBase of next IO thread. Each IO thread then calls loopForEver() for its EventBase, which essentially calls epoll() to perform async io.

    enter image description here

    So most of the time you should probably be using a CPUThreadPoolExecutor, as that is the usual use case for having a pool of workers.