]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/math/vectors/simd/simd-docs.factor
factor: trim using lists
[factor.git] / basis / math / vectors / simd / simd-docs.factor
index 540838bdd5b1705b8970a64a4f84c1ad1b4cf731..68592cb06b13a6f4324fca2641d63cc1e57790d4 100644 (file)
@@ -1,6 +1,6 @@
 USING: classes.tuple.private cpu.architecture help.markup
-help.syntax kernel.private math math.vectors math.vectors.simd.intrinsics
-sequences ;
+help.syntax kernel.private math.vectors
+math.vectors.simd.intrinsics sequences ;
 IN: math.vectors.simd
 
 ARTICLE: "math.vectors.simd.intro" "Introduction to SIMD support"
@@ -8,7 +8,7 @@ ARTICLE: "math.vectors.simd.intro" "Introduction to SIMD support"
 $nl
 "SIMD support in the processor takes the form of instruction sets which operate on vector registers. By operating on multiple scalar values at the same time, code which operates on points, colors, and other vector data can be sped up."
 $nl
-"In Factor, SIMD support is exposed in the form of special-purpose SIMD " { $link "sequence-protocol" } " implementations. These are fixed-length, homogeneous sequences. They are referred to as vectors, but should not be confused with Factor's " { $link "vectors" } ", which can hold any type of object and can be resized.)."
+"In Factor, SIMD support is exposed in the form of special-purpose SIMD " { $link "sequence-protocol" } " implementations. These are fixed-length, homogeneous sequences. They are referred to as vectors, but should not be confused with Factor's " { $link "vectors" } ", which can hold any type of object and can be resized."
 $nl
 "The words in the " { $vocab-link "math.vectors" } " vocabulary, which can be used with any sequence of numbers, are special-cased by the compiler. If the compiler can prove that only SIMD vectors are used, it expands " { $link "math-vectors" } " into " { $link "math.vectors.simd.intrinsics" } ". While in the general case, SIMD intrinsics operate on heap-allocated SIMD vectors, that too can be optimized since in many cases the compiler unbox SIMD vectors, storing them directly in registers."
 $nl
@@ -23,20 +23,20 @@ $nl
 $nl
 "SSE2 introduces double-precision SIMD (" { $snippet "double-2" } ") and integer SIMD (all types). Integer SIMD is missing a few features; in particular, the " { $link vmin } " and " { $link vmax } " operations only work on " { $snippet "uchar-16" } " and " { $snippet "short-8" } "."
 $nl
-"SSE3 introduces horizontal adds (summing all components of a single vector register), which are useful for computing dot products. Where available, SSE3 operations are used to speed up " { $link sum } ", " { $link v. } ", " { $link norm-sq } ", " { $link norm } ", and " { $link distance } "."
+"SSE3 introduces horizontal adds (summing all components of a single vector register), which are useful for computing dot products. Where available, SSE3 operations are used to speed up " { $link sum } ", " { $link vdot } ", " { $link norm-sq } ", " { $link norm } ", and " { $link distance } "."
 $nl
 "SSSE3 introduces " { $link vabs } " for " { $snippet "char-16" } ", " { $snippet "short-8" } " and " { $snippet "int-4" } "."
 $nl
-"SSE4.1 introduces " { $link vmin } " and " { $link vmax } " for all remaining integer types, a faster instruction for " { $link v. } ", and a few other things."
+"SSE4.1 introduces " { $link vmin } " and " { $link vmax } " for all remaining integer types, a faster instruction for " { $link vdot } ", and a few other things."
 $nl
 "On PowerPC, or older x86 chips without SSE, software fallbacks are used for all high-level vector operations. SIMD code can run with no loss in functionality, just decreased performance."
 $nl
-"The primities in the " { $vocab-link "math.vectors.simd.intrinsics" } " vocabulary do not have software fallbacks, but they should not be called directly in any case." ;
+"The primitives in the " { $vocab-link "math.vectors.simd.intrinsics" } " vocabulary do not have software fallbacks, but they should not be called directly in any case." ;
 
 ARTICLE: "math.vectors.simd.types" "SIMD vector types"
 "Each SIMD vector type is named " { $snippet "scalar-count" } ", where " { $snippet "scalar" } " is a scalar C type and " { $snippet "count" } " is a vector dimension."
 $nl
-"The following vector types are available:"
+"The following 128-bit vector types are defined in the " { $vocab-link "math.vectors.simd" } " vocabulary:"
 { $code
     "char-16"
     "uchar-16"
@@ -48,12 +48,25 @@ $nl
     "ulonglong-2"
     "float-4"
     "double-2"
+}
+"Double-width 256-bit vector types are defined in the " { $vocab-link "math.vectors.simd.cords" } " vocabulary:"
+{ $code
+    "char-32"
+    "uchar-32"
+    "short-16"
+    "ushort-16"
+    "int-8"
+    "uint-8"
+    "longlong-4"
+    "ulonglong-4"
+    "float-8"
+    "double-4"
 } ;
 
 ARTICLE: "math.vectors.simd.words" "SIMD vector words"
 "For each SIMD vector type, several words are defined, where " { $snippet "type" } " is the type in question:"
 { $table
-    { "Word" "Stack effect" "Description" }
+    { { $strong "Word" } { $strong "Stack effect" } { $strong "Description" } }
     { { $snippet "type-with" } { $snippet "( x -- simd-array )" } "creates a new instance where all components are set to a single scalar" }
     { { $snippet "type-boa" } { $snippet "( ... -- simd-array )" } "creates a new instance where components are read from the stack" }
     { { $snippet "type-cast" } { $snippet "( simd-array -- simd-array' )" } "creates a new SIMD array where the underlying data is taken from another SIMD array, with no format conversion" }
@@ -72,7 +85,7 @@ $nl
 $nl
 "For example, in the following, no SIMD operations are used at all, because the compiler's propagation pass does not consider dynamic variable usage:"
 { $code
-"""USING: compiler.tree.debugger math.vectors
+"USING: compiler.tree.debugger math.vectors
 math.vectors.simd ;
 SYMBOLS: x y ;
 
@@ -80,10 +93,10 @@ SYMBOLS: x y ;
     float-4{ 1.5 2.0 3.7 0.4 } x set
     float-4{ 1.5 2.0 3.7 0.4 } y set
     x get y get v+
-] optimizer-report.""" }
+] optimizer-report." }
 "The following word benefits from SIMD optimization, because it begins with an unsafe declaration:"
 { $code
-"""USING: compiler.tree.debugger kernel.private
+"USING: compiler.tree.debugger kernel.private
 math.vectors math.vectors.simd ;
 IN: simd-demo
 
@@ -91,12 +104,12 @@ IN: simd-demo
     { float-4 float-4 float-4 } declare
     [ v* ] [ [ 1.0 ] dip n-v v* ] bi-curry* bi v+ ;
 
-\\ interpolate optimizer-report.""" }
+\\ interpolate optimizer-report." }
 "Note that using " { $link declare } " is not recommended. Safer ways of getting type information for the input parameters to a word include defining methods on a generic word (the value being dispatched upon has a statically known type in the method body), as well as using " { $link "hints" } " and " { $link POSTPONE: inline } " declarations."
 $nl
 "Here is a better version of the " { $snippet "interpolate" } " words above that uses hints:"
 { $code
-"""USING: compiler.tree.debugger hints
+"USING: compiler.tree.debugger hints
 math.vectors math.vectors.simd ;
 IN: simd-demo
 
@@ -105,14 +118,14 @@ IN: simd-demo
 
 HINTS: interpolate float-4 float-4 float-4 ;
 
-\\ interpolate optimizer-report. """ }
+\\ interpolate optimizer-report. " }
 "This time, the optimizer report lists calls to both SIMD primitives and high-level vector words, because hints cause two code paths to be generated. The " { $snippet "optimized." } " word can be used to make sure that the fast code path consists entirely of calls to primitives."
 $nl
 "If the " { $snippet "interpolate" } " word was to be used in several places with different types of vectors, it would be best to declare it " { $link POSTPONE: inline } "."
 $nl
 "In the " { $snippet "interpolate" } " word, there is still a call to the " { $link <tuple-boa> } " primitive, because the return value at the end is being boxed on the heap. In the next example, no memory allocation occurs at all because the SIMD vectors are stored inside a struct class (see " { $link "classes.struct" } "); also note the use of inlining:"
 { $code
-"""USING: compiler.tree.debugger math.vectors math.vectors.simd ;
+"USING: compiler.tree.debugger math.vectors math.vectors.simd ;
 IN: simd-demo
 
 STRUCT: actor
@@ -125,24 +138,29 @@ GENERIC: advance ( dt object -- )
 
 : update-velocity ( dt actor -- )
     [ acceleration>> n*v ] [ velocity>> v+ ] [ ] tri
-    (>>velocity) ; inline
+    velocity<< ; inline
 
 : update-position ( dt actor -- )
     [ velocity>> n*v ] [ position>> v+ ] [ ] tri
-    (>>position) ; inline
+    position<< ; inline
 
 M: actor advance ( dt actor -- )
     [ >float ] dip
     [ update-velocity ] [ update-position ] 2bi ;
 
-M\\ actor advance optimized."""
+M\\ actor advance optimized."
 }
-"The " { $vocab-link "compiler.cfg.debugger" } " vocabulary can give a lower-level picture of the generated code, that includes register assignments and other low-level details. To look at low-level optimizer output, call " { $snippet "test-mr mr." } " on a word or quotation:"
+"The " { $vocab-link "compiler.cfg.debugger" } " vocabulary can give a lower-level picture of the generated code, that includes register assignments and other low-level details. To look at low-level optimizer output, call " { $snippet "regs." } " on a word or quotation:"
 { $code
-"""USE: compiler.tree.debugger
+"USE: compiler.tree.debugger
 
-M\\ actor advance test-mr mr.""" }
-"An example of a high-performance algorithm that uses SIMD primitives can be found in the " { $vocab-link "benchmark.nbody-simd" } " vocabulary." ;
+M\\ actor advance regs." }
+"Example of a high-performance algorithms that use SIMD primitives can be found in the following vocabularies:"
+{ $list
+    { $vocab-link "benchmark.nbody-simd" }
+    { $vocab-link "benchmark.raytracer-simd" }
+    { $vocab-link "random.sfmt" }
+} ;
 
 ARTICLE: "math.vectors.simd.intrinsics" "Low-level SIMD primitives"
 "The words in the " { $vocab-link "math.vectors.simd.intrinsics" } " vocabulary are used to implement SIMD support. These words have three disadvantages compared to the higher-level " { $link "math-vectors" } " words:"