[WIP] eventify: removed support for non-prioritized task_types #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "m.zych/fmsolvr:WIP/parallelization/intra-node/lgpl21+minimize"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This change drops support for non-prioritized task_types from Eventify and requires FMSolvr to specify all of its task_types at compile-time. Essentially, - the flexibility of storing polymorphically non-prioritized tasks in a single queue of BaseTasks in each MultiQueue<> instance, and - the ability to specify non-prioritized task_types at run-time have been removed from Eventify. Superficially, this might sound negative. However, if an Eventify client needs the removed features, it can still: - implement a polymorphic value type, representing a task of any type, using run-time concept idiom, - and then, pass that class as the last task_type to the MulitQueue<>. This effectively will imitate the existence of a single queue storing polymorphically all non-prioritized tasks, without any loss of efficiency. The opposite is not true, however - always creating a queue of BaseTasks forces all Eventify clients to pay for run-time polymorphism, even in cases, when it is entirely unnecessary, such as in FMSolver. More info about the run-time concept idiom can be found here: - NDC { London } Sean Parent - Better Code: Runtime Polymorphism ~ https://www.youtube.com/watch?v=QGcVXgEVMJg ~ https://sean-parent.stlab.cc/papers-and-presentationsBefore this change, Tasks were stored in concurrent_queues indirectly, through pointers: +--------------------------------- -----+ concurrent_queue | | | | | | | | | ... | | +-|---|---|---|---|---|---|---|--- ---|-+ | | | | | | | | | V | V | V | V | V +---+ | +---+ | +---+ | +---+ | +---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---+ | +---+ | +---+ | +---+ | +---+ Tasks V V V V +---+ +---+ +---+ +---+ | | | | | | | | | | | | | | | | | | | | | | | | +---+ +---+ +---+ +---+ However, dynamically-allocating each Task is not necessary, since Eventify requires specifying all task_types at compile-time. This essentially means that a MultiQueue can be represented as a std::tuple<> of concurrent_queues, each storing directly (by value) Tasks of a single task_type: +--------------------------------- -----+ concurrent_queue | | | | | | | | | | | | | | | | | | | | ... | | Tasks | | | | | | | | | | | +--------------------------------- -----+ Note that, before the change "eventify: removed abstract class BaseTask", each MultiQueue contained single concurrent_queue dedicated to storing polymorphically Tasks of all non-priorities task_types. This explains why Tasks were dynamically-allocated and stored indirectly (by pointer), that is, in C++ polymorphic value_types require specialized implementation, thus developers often use pointers, which are polymorphic out-of-the-box. Unfortunately, this change is suboptimal, because semantically each TaskFactory::CreateAndEnqueueTask() operation creates a couple of redundant Task copies, which can be optimized away, but that optimization is not guaranteed. Ideally, invoking TaskFactory::CreateAndEnqueueTask() would result in emplacing a Task directly in a concurrent_queue. However, such implementation would require non-trivial refactoring of the TaskFactory, LoadBalancer and MultiQueue classes, therefore, for the time being, Eventify will rely on the optimizer to eliminate redundant copies.[WIP] eventify: removed support for non-prioritized Tasks and stopped dynamically-allocating Tasksto [WIP] eventify: removed support for non-prioritized task_types