Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The first form is easier to send to 32 beefy cores or 1024 small CPUs or a Beowulf cluster or a GPU or people sitting in a room.


Both of them have to be completely rewritten to make use of multiprocessing, so what exactly is the advantage?


The original example isn't really using ranges except to emulate C++98 iterator work though.

The actual equivalent might be something closer to:

    inline double algorithm_call(std::span<double const> xs) noexcept {
        return std::accumulate(
            xs, 0.0,
            [](double acc, double volts) {
                auto mv  = calibrated_mv(volts);
                auto err = residual(mv);
                return weighted_square(err) + acc;
        });
    }
(that is, without the boilerplate .begin and .end).

Even that is enough to make ranges useful in my mind, but in a codebase which has started to integrate some functional programming techniques, there are also applications for things like views and transforms.

This can make it easier to reason about iteration pipelines in ways you might already be familiar with from POSIX.

That all said, it's C++ so sometimes the error messages get a lot more 'interesting' than they would have with STL-style iterators, especially when mixed with constexpr expressions as you might do with std::format or fmt libs.


The first one too? Isn't that the map-reduce fork-join golden example of multiprocessing?


`std::accumulate` is defined to have sequential semantics, so the analysis required to make it parallel is probably not that different than starting from the loop version. I guess you could have an alternate `accumulate_associative` that uses the same interface but assumes the reduction is associative and has unspecified evaluation order?


C++ has std::reduce for that, which is std::accumulate except it's defined to operate without any specific ordering.


Thanks everyone, my C++ knowledge has been greatly expanded today.


And now you should probably also stop and consider whether adding elements one-by-one as opposed to recursively adding together sums of smaller subarrays has better or worse numerical behaviour in regards to e.g. rounding and stability.


std::accumulate is sequential and guarantes in order traversal. std::reduce is parallel version of it


1) afaik accumulate cannot be parallelized

2) the map part is included in the accumulate lambda, so the map part cannot be parallelized either -> you'd have to split it out into a transform step (iirc)


It's been 15 years since I've last touched OpenMP, but the second form is trivially parallelizable as well. Besides, this parallelization can only ever properly work with arrays/vectors or, at the very worst, std::deque as its usually implemented (a vector of fixed-length arrays), not with e.g. linked lists or red-black trees, so why even bother with generic spans and algorithms?


For compilation?




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: