executors / executors

A proposal for a executor programming model for ISO C++
136 stars 21 forks source link

Permit SIMD executors with floating point implications #483

Open jaredhoberock opened 4 years ago

jaredhoberock commented 4 years ago

From Billy:

Consider a possible implementation: struct simd_executor : inline_executor { // first, satisfy executor >requirements via inheritance template simd_sender bulk_execute(F f, size_t n) const {

pragma simd

for(size_t i = 0; i != n; ++i) { std::invoke(f, i); }

return {}; } }; To accelerate bulk_execute, simd_executor uses a SIMD loop.

That is not a valid implementation because #pragma simd has floating point model implications. (Notably, there's nothing proposed for C++ that would allow use of something like #pragma simd, neither execution::vec nor execution::par_unseq can do that. vec and par_unseq discuss forward progress guarantees and available concurrency, not floating point transformations.) So if P0443's authors want something like #pragma simd behavior I'm not sure how that dovetails with executors which talk about where the work runs, because #pragma simd's primary change is not about where the work runs but about the work itself.

lewissbaker commented 4 years ago

Is the intent that it is actually #pragma simd (which i believe under some compilers allows non-standard float behaviour) or should this example be change to the weaker form of #pragma ivdep?

mjgarland commented 4 years ago

I'm not sure it matters a great deal for this example. As I recall, we've generally used #pragma simd in examples rather than #pragma ivdep because the former forces SIMD execution while the latter does not. Using #pragma omp simd would be another option that is likely more portable across compilers.

While I don't think it matters a lot for this example, I also don't think we should do something that would forbid programmers from writing an executor using #pragma simd if they're motivated to do so.