Skip to content

[C++] Constexpr implementation for dynamic dispatch #49835

@AntoinePrv

Description

@AntoinePrv

Describe the enhancement requested

Right now the DynamicDispatch makes no assumption on the DynamicFunction::implementations().
However in practice we can assume the implementations to be a compile-time sequence: each available must have been compiled so there is no possibility to add more at runtime (doing so would require a dlopen style plugin loading, which I don't believe is what we want to go towards).

With C++17 and CTAD, it is straightforward to use a static array without needing with compile-time array sizes.
For e.g. it is already done with:

return std::array{
#if defined(ARROW_HAVE_SSE4_2)
Implementation{DispatchLevel::NONE, &bpacking::unpack_sse4_2<Uint>},
#else
Implementation{DispatchLevel::NONE, &bpacking::unpack_scalar<Uint>},
#endif
#if defined(ARROW_HAVE_RUNTIME_AVX2)
Implementation{DispatchLevel::AVX2, &bpacking::unpack_avx2<Uint>},
#endif
#if defined(ARROW_HAVE_RUNTIME_AVX512)
Implementation{DispatchLevel::AVX512, &bpacking::unpack_avx512<Uint>},
#endif
};

There are actually few places to change such as:

static std::vector<std::pair<DispatchLevel, FunctionType>> implementations() {
return {{DispatchLevel::NONE, standard::FindMinMaxImpl}
#if defined(ARROW_HAVE_RUNTIME_AVX2)
,
{DispatchLevel::AVX2, FindMinMaxAvx2}
#endif
};

This will be a small immediate yet negligible improvement (the std::vector is actually just parsed once).
The big win, is to use that information to skip dynamic dispatch altogether when there is only one implementation available, as done (verbosly) here:

#if defined(ARROW_HAVE_NEON)
return bpacking::unpack_neon(in, out, opts);
#else
static DynamicDispatch<UnpackDynamicFunction<Uint> > dispatch;
return dispatch.func(in, out, opts);
#endif

But not done below:

MinMax FindMinMax(const int16_t* levels, int64_t num_levels) {
static DynamicDispatch<MinMaxDynamicFunction> dispatch;
return dispatch.func(levels, num_levels);
}

Component(s)

C++

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions