Taking advantage of virtual actors

In the last section, we developed a naive implementation of a Fibonacci sequence actor. Naive because, generally, a proper recursive implementation should use memoization to cache intermediate results, and speed-up the computation.

However, at first sight, a memoization approach will be difficult to implement under the rules of the actor model where sharing memory (a cache, for example) is forbidden. We could create a central cache actor, but because actors are single-threaded by design, it would introduce a central bottleneck.

Fortunately, a virtual actor model provides horizontal actors. Therefore, in Ultramarine, two calls to ultramarine::get<fibonacci_actor>(index_number) will always point to the same actor. We can take advantage of this by having each actor remember it’s value.

Introducing caching

First, we need to introduce a state into our actor:

class fibonacci_actor : public ultramarine::actor<fibonacci_actor> {
    std::optional<int> result;
public:
    ULTRAMARINE_DEFINE_ACTOR(fibonacci_actor, (fib));
    seastar::future<int> fib(); // compute Fibonacci number for index `this->key`
};

The variable result can now store the Fibonacci number specific to this actor. We modify our message handler to store its result and reuse it upon further messages:

seastar::future<int> fibonacci_actor::fib() {
    if (key <= 2) {
        return seastar::make_ready_future<int>(1);
    } else if (result) {
        return seastar::make_ready_future<int>(*result);
    } else {
        auto f1 = ultramarine::get<fibonacci_actor>(key - 1)->fib();
        auto f2 = ultramarine::get<fibonacci_actor>(key - 2)->fib();
        return seastar::when_all_succeed(std::move(f1), std::move(f2)).then([this] (auto r1, auto r2) {
            return result = r1 + r2;
        });
    }
}

Performance caparison

Executing the above code a couple of time and averaging the results, we get:

Index number No caching Cached Speedup
24 9661 us 952 us ~10x
25 15327 us 1160 us ~13x
26 24957 us 1427 us ~17x
27 41202 us 1893 us ~22x