about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2023-07-27 13:21:56 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2023-07-27 13:21:56 -0400
commit6e8d21ee760d4672ed6c374c9be1687c531499fb (patch)
treeae7b8d067c16e85fc3e40e283e0b8f72b693d561
parent7c7dbe0c505ccbc02ff30c1e37381ab1d47bf46f (diff)
downloadrust-6e8d21ee760d4672ed6c374c9be1687c531499fb.tar.gz
rust-6e8d21ee760d4672ed6c374c9be1687c531499fb.zip
Define portability
-rw-r--r--crates/core_simd/src/core_simd_docs.md33
-rw-r--r--crates/core_simd/src/mod.rs3
2 files changed, 35 insertions, 1 deletions
diff --git a/crates/core_simd/src/core_simd_docs.md b/crates/core_simd/src/core_simd_docs.md
index 15e8ed0253e..3d2e737e2af 100644
--- a/crates/core_simd/src/core_simd_docs.md
+++ b/crates/core_simd/src/core_simd_docs.md
@@ -2,3 +2,36 @@ Portable SIMD module.
 
 This module offers a portable abstraction for SIMD operations
 that is not bound to any particular hardware architecture.
+
+# What is "portable"?
+
+This module provides a SIMD implementation that is fast and predictable on any target.
+
+### Portable SIMD works on every target
+
+Unlike target-specific SIMD in `std::arch`, portable SIMD compiles for every target.
+In this regard, it is just like "regular" Rust.
+
+### Portable SIMD is consistent between targets
+
+A program using portable SIMD can expect identical behavior on any target.
+In most regards, [`Simd<T, N>`] can be thought of as a parallelized `[T; N]` and operates like a sequence of `T`.
+
+This has one notable exception: a handful of older architectures (e.g. `armv7` and `powerpc`) flush [subnormal](`f32::is_subnormal`) `f32` values to zero.
+On these architectures, subnormal `f32` input values are replaced with zeros, and any operation producing subnormal `f32` values produces zeros instead.
+This doesn't affect most architectures or programs.
+
+### Operations use the best instructions available
+
+Operations provided by this module compile to the best available SIMD instructions.
+
+Portable SIMD is not a low-level vendor library, and operations in portable SIMD _do not_ necessarily map to a single instruction.
+Instead, they map to a reasonable implementation of the operation for the target.
+
+Consistency between targets is not compromised to use faster or fewer instructions.
+In some cases, `std::arch` will provide a faster function that has slightly different behavior than the `std::simd` equivalent.
+For example, [`_mm_min_ps`](`core::arch::x86_64::_mm_min_ps`) can be slightly faster than [`SimdFloat::simd_min`], but does not conform to the IEEE standard also used by [`f32::min`].
+When necessary, [`Simd<T, N>`] can be converted to the types provided by `std::arch` to make use of target-specific functions.
+
+Many targets simply don't have SIMD, or don't support SIMD for a particular element type.
+In those cases, regular scalar operations are generated instead.
diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs
index f9891a3b7c1..dd954b7cc48 100644
--- a/crates/core_simd/src/mod.rs
+++ b/crates/core_simd/src/mod.rs
@@ -21,8 +21,9 @@ mod swizzle_dyn;
 mod vector;
 mod vendor;
 
-#[doc = include_str!("core_simd_docs.md")]
 pub mod simd {
+    #![doc = include_str!("core_simd_docs.md")]
+
     pub mod prelude;
 
     pub(crate) use crate::core_simd::intrinsics;