[skvx] add reduce add

* Slight awkwardness as the SSE instruction emits the equivalent shuffle reduce in microcode, and can be slow, so instead explicitly write out the shuffle reduce. This is still faster than a scalar reduction, as the depth of the recursive reduction is log2(n) versus n for scalar reduction.

// Pseudo-assembly dependency comparison (N=4 example):
//
// Without this function (Naive Scalar):
//   ADD  r_sum, lane0, lane1    // Step 1
//   ADD  r_sum, r_sum, lane2    // Step 2 (Stalls waiting for Step 1)
//   ADD  r_sum, r_sum, lane3    // Step 3 (Stalls waiting for Step 2) -> Latency: 3 adds
//
// With this function (SIMD Tree):
//   SHUF v_shuf, v_vec, ...     // Setup
//   VADD v_vec,  v_vec, v_shuf  // Step 1 (Computes 0+1 and 2+3 in parallel)
//   SHUF v_shuf, v_vec, ...     // Setup
//   VADD v_vec,  v_vec, v_shuf  // Step 2 (Stalls waiting for Step 1) -> Latency: 2 adds

* This CL only adds dedicated instructions for floats, instructions for other types can be added.

Calculating ArcLengths, M4, before:
  24/24  MB     195     25.8µs  26.5µs  26.4µs  26.7µs  1%      ▅▇▄▄▁▆█▇▄▇      grmtl   ArcLength_Combined
  25/25  MB     238     20.9µs  21µs    21µs    21.3µs  1%      █▃▁▂▄▄▁▆▃▂      grmtl   ArcLength_Cubic
  26/26  MB     166     30.1µs  30.6µs  30.6µs  31.5µs  1%      ▁▂▂▃▅▂█▄▄▃      grmtl   ArcLength_Conic

Calculating ArcLengths after:
  25/25  MB     240     20.7µs  21µs    21µs    21.4µs  1%      ██▆▁▂▅▂▄▃▁      grmtl   ArcLength_Combined
  24/25  MB     302     16.4µs  16.6µs  16.6µs  16.8µs  1%      ▆▄▃▄█▇▁▄▅▄      grmtl   ArcLength_Cubic
  25/25  MB     206     24.1µs  24.3µs  24.3µs  24.5µs  0%      ▁▄▂▃▂▅█▃▅▇      grmtl   ArcLength_Conic

Change-Id: Ic4595698e4a4503544404019e9b385f55a7f9f28
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1290796
Reviewed-by: Kaylee Lubick <kjlubick@google.com>
Commit-Queue: Thomas Smith <thomsmit@google.com>
1 file changed