fearless_simd 1.0.0

Safer and easier SIMD
Documentation
# Avoiding #[simd] proc macro with manual inlining

The use of `#[simd]` is recommended as the more ergonomic option. This document describes how to achieve the same effect manually, if you have to.

## TL;DR

- All SIMD functions need `#[inline(always)]`.
- Use `dispatch!` when calling SIMD code from non-SIMD code.
- Use `vectorize()` when calling SIMD from SIMD if you don't want to force inlining.

## A slightly longer explanation

Calls to SIMD functions have to be made from a function annotated `#[target_feature(enable = ...)]`, to let the compiler know that the CPU instructions required for SIMD are available within this function. `dispatch!` and `vectorize()` add the appropriate `#[target_feature(enable = ...)]` annotations, but there is your code between `dispatch!` which sets these annotations and fearless_simd functions like `f32x4.sqrt()` which need that annotation for performance.

The contents of a function annotated `#[inline(always)]` will always be copy-pasted into the caller by the compiler. The compiler may decide to do this as an optimization anyway, but `#[inline(always)]` forces this behavior. This lets you erase the boundaries of code that sits between `dispatch!`/`vectorize()` and the code that wants to emit SIMD instructions.

The `#[simd]` macro solves this by rewriting

```rust
fn foo<S: Simd>(simd: S, ...) {
    // Original body
}
```

into something close to this:

```rust
fn foo<S: Simd>(simd: S, ...) {
    simd.vectorize(
        #[inline(always)]
        || {
            // Original body
        },
    )
}
```

Which solves the problem but requires too much boilerplate to write this out manually every time. Hence the recommendation to annotate functions with the shorter `#[inline(always)]` and insert calls to `vectorize()` when you need to break up the inlining.

## Further reading

[The article describing the design](https://shnatsel.github.io/safe-simd-in-rust-even-on-the-inside/#the-abi-would-like-a-word) explains why this is needed from first principles and how we arrived to this design.

There's also Q&A on [Zulip](https://xi.zulipchat.com/#narrow/channel/514230-simd/topic/inlining/with/546913433).