Hello SIMD World
TIP
You can do this exercise locally or on Compiler Explorer.
Boilerplate:
#include <simd>
#include <print>
namespace simd = std::simd;
int main() {
return 0;
}
Test simd constructors
- Test the four different constructors:
- default
- broadcast
- generator
- load (conversion from statically sized range)
- And test construction via
unchecked_loadandpartial_load.… using different element types:
double,char,unsigned, …Check what happens if you use a non-vectorizable type.
Test different number of elements.
Examples
simd::vec<double> v = 1.; // broadcast simd::vec<int> iota([](int i) { return ...; }); // generator simd::vec str = "Hello World"; // CTAD + load constructor
Unaligned access
Do an aligned load on an unaligned address.
TIP
You just learned a new reason for SIGSEGV. Remember this when your future self stares at the debugger, puzzled how the pointer can be out-of-bounds…
Implement abs(simd)
Implement and test the absolute value function (not using
simd::abs):template <typename T, typename A> constexpr simd::basic_vec<T, A> abs(simd::basic_vecT, A> x) { // TODO }Note that a correct
std::absimplementation cares about-0.. Bonus points if you have an idea. 😉
TIP
simd::select(basic_mask, basic_vec, basic_vec)std::bit_cast
Linear search
Given a
std::string_view(which is a contiguous range ofchars),
- … count the number of spaces.
- … return the index of the first occurrence of a given char.
- … (optional) return the index of the first occurrence of a given substring.
int count_spaces(std::string_view s) { // TODO } int find(std::string_view s, char c) { // TODO } int find(std::string_view s, std::string_view s) { // TODO }
TIP
simd::reduce_count(basic_mask)simd::reduce_min_index(basic_mask)
Optional 1: simd_for_each
Write a
simd_for_eachalgorithm that takes a range and a generic callable:template <std::contiguous_range R> void simd_for_each(R&& rng, auto&& fun) { // Load simd's from std::ranges::data(rng) and invoke fun with each. // Consider how and when to write back a modified simd. // don't forget the epilogue }
TIP
For a completely generic solution you might want to use: