Runtime: Use hardware intrinsics

Created on 20 Nov 2017  路  6Comments  路  Source: dotnet/runtime

Intel and others are adding support for general use of hardware intrinsics (as opposed to code explicitly recognized by code gen which is the approach of Vector).

As these come on line, use them where they help: eg string searching, regex, CRC, ...

area-Meta enhancement

Most helpful comment

I've started an experimental branch on my fork which updates System.Numerics.Vector to use hardware intrinsics: https://github.com/tannergooding/corefx/tree/vector-intrinsics.

I believe it will give a good feel for how the hardware intrinsics may actually be used and will also be useful for validating that the hardware intrinsics are behaving properly (https://github.com/dotnet/coreclr/issues/15490).

The implementation is being ported from https://github.com/Microsoft/DirectXMath.

CC. @eerhardt, @fiigii

All 6 comments

I've started an experimental branch on my fork which updates System.Numerics.Vector to use hardware intrinsics: https://github.com/tannergooding/corefx/tree/vector-intrinsics.

I believe it will give a good feel for how the hardware intrinsics may actually be used and will also be useful for validating that the hardware intrinsics are behaving properly (https://github.com/dotnet/coreclr/issues/15490).

The implementation is being ported from https://github.com/Microsoft/DirectXMath.

CC. @eerhardt, @fiigii

Putting a semi arbitrary cost.

I have some early numbers (for Vector4) when using HWIntrinsics and they look good (see https://github.com/dotnet/corefx/issues/25386#issuecomment-351258902 for branch info).

NOTES:

  • The HWIntrinsic code is only using VEX encoded SSE instructions, while the JIT Intrinsic code is using AVX instructions in a couple places (such as Dot).
  • The HWIntrinsic code doesn't have full containment support for Sse.Load or Sse.Store yet

With that being said, the numbers are nearly identical in most cases and in some cases (like Normalize) are actually more performant.

JIT Intrinsic

| System.Numerics.Vectors.Performance.Tests.dll | Metric | Unit | Iterations | Average | STDEV.S | Min | Max |
| ---------------------------------------------------------------------------- | -------- | ---- | ---------- | -------- | ------- | -------- | -------- |
| System.Numerics.Tests.Perf_Vector4.AddFunctionBenchmark | Duration | msec | 100 | 83.863 | 0.910 | 83.656 | 91.902 |
| System.Numerics.Tests.Perf_Vector4.AddOperatorBenchmark | Duration | msec | 100 | 83.787 | 0.047 | 83.648 | 83.894 |
| System.Numerics.Tests.Perf_Vector4.DistanceBenchmark | Duration | msec | 60 | 167.701 | 2.604 | 167.263 | 187.485 |
| System.Numerics.Tests.Perf_Vector4.DistanceJitOptimizeCanaryBenchmark | Duration | msec | 50 | 200.146 | 0.273 | 199.479 | 201.208 |
| System.Numerics.Tests.Perf_Vector4.DistanceSquaredBenchmark | Duration | msec | 60 | 167.649 | 0.218 | 167.390 | 168.764 |
| System.Numerics.Tests.Perf_Vector4.DistanceSquaredJitOptimizeCanaryBenchmark | Duration | msec | 52 | 195.181 | 0.013 | 195.162 | 195.224 |
| System.Numerics.Tests.Perf_Vector4.DotBenchmark | Duration | msec | 60 | 167.298 | 0.017 | 167.274 | 167.368 |
| System.Numerics.Tests.Perf_Vector4.DotJitOptimizeCanaryBenchmark | Duration | msec | 60 | 168.187 | 2.934 | 167.297 | 185.213 |
| System.Numerics.Tests.Perf_Vector4.GetHashCodeBenchmark | Duration | msec | 27 | 383.927 | 2.218 | 379.433 | 388.080 |
| System.Numerics.Tests.Perf_Vector4.GetHashCodeJitOptimizeCanaryBenchmark | Duration | msec | 21 | 476.312 | 1.026 | 474.746 | 478.693 |
| System.Numerics.Tests.Perf_Vector4.LengthBenchmark | Duration | msec | 72 | 139.675 | 1.227 | 139.377 | 149.843 |
| System.Numerics.Tests.Perf_Vector4.LengthJitOptimizeCanaryBenchmark | Duration | msec | 60 | 167.533 | 0.724 | 167.283 | 172.956 |
| System.Numerics.Tests.Perf_Vector4.LengthSquaredBenchmark | Duration | msec | 72 | 139.695 | 0.208 | 139.456 | 140.748 |
| System.Numerics.Tests.Perf_Vector4.LengthSquaredJitOptimizeCanaryBenchmark | Duration | msec | 60 | 167.525 | 1.096 | 167.239 | 174.436 |
| System.Numerics.Tests.Perf_Vector4.MultiplyFunctionBenchmark | Duration | msec | 100 | 83.650 | 0.012 | 83.631 | 83.700 |
| System.Numerics.Tests.Perf_Vector4.MultiplyOperatorBenchmark | Duration | msec | 100 | 83.644 | 0.019 | 83.618 | 83.729 |
| System.Numerics.Tests.Perf_Vector4.NormalizeBenchmark | Duration | msec | 8 | 1405.377 | 0.132 | 1405.188 | 1405.539 |
| System.Numerics.Tests.Perf_Vector4.NormalizeJitOptimizeCanaryBenchmark | Duration | msec | 7 | 1520.420 | 0.327 | 1520.049 | 1521.076 |
| System.Numerics.Tests.Perf_Vector4.SquareRootBenchmark | Duration | msec | 45 | 223.362 | 0.106 | 223.083 | 223.590 |
| System.Numerics.Tests.Perf_Vector4.SquareRootJitOptimizeCanaryBenchmark | Duration | msec | 28 | 362.799 | 0.081 | 362.683 | 363.020 |
| System.Numerics.Tests.Perf_Vector4.SubtractFunctionBenchmark | Duration | msec | 100 | 83.750 | 0.093 | 83.652 | 84.448 |
| System.Numerics.Tests.Perf_Vector4.SubtractOperatorBenchmark | Duration | msec | 100 | 83.643 | 0.028 | 83.613 | 83.843 |

Hardware Intrinsic

| System.Numerics.Vectors.Performance.Tests.dll | Metric | Unit | Iterations | Average | STDEV.S | Min | Max |
| ---------------------------------------------------------------------------- | -------- | ---- | ---------- | -------- | ------- | -------- | -------- |
| System.Numerics.Tests.Perf_Vector4.AddFunctionBenchmark | Duration | msec | 100 | 83.700 | 0.466 | 83.617 | 88.302 |
| System.Numerics.Tests.Perf_Vector4.AddOperatorBenchmark | Duration | msec | 100 | 83.728 | 0.025 | 83.699 | 83.874 |
| System.Numerics.Tests.Perf_Vector4.DistanceBenchmark | Duration | msec | 60 | 167.731 | 0.178 | 167.376 | 168.594 |
| System.Numerics.Tests.Perf_Vector4.DistanceJitOptimizeCanaryBenchmark | Duration | msec | 50 | 200.356 | 0.081 | 200.286 | 200.888 |
| System.Numerics.Tests.Perf_Vector4.DistanceSquaredBenchmark | Duration | msec | 60 | 168.159 | 3.625 | 167.264 | 189.158 |
| System.Numerics.Tests.Perf_Vector4.DistanceSquaredJitOptimizeCanaryBenchmark | Duration | msec | 52 | 195.201 | 0.044 | 195.149 | 195.385 |
| System.Numerics.Tests.Perf_Vector4.DotBenchmark | Duration | msec | 60 | 167.760 | 0.183 | 167.376 | 168.348 |
| System.Numerics.Tests.Perf_Vector4.DotJitOptimizeCanaryBenchmark | Duration | msec | 52 | 195.189 | 0.054 | 195.137 | 195.463 |
| System.Numerics.Tests.Perf_Vector4.GetHashCodeBenchmark | Duration | msec | 27 | 382.175 | 2.378 | 380.232 | 391.537 |
| System.Numerics.Tests.Perf_Vector4.GetHashCodeJitOptimizeCanaryBenchmark | Duration | msec | 21 | 482.472 | 4.269 | 476.152 | 490.759 |
| System.Numerics.Tests.Perf_Vector4.LengthBenchmark | Duration | msec | 72 | 139.771 | 2.468 | 139.373 | 160.399 |
| System.Numerics.Tests.Perf_Vector4.LengthJitOptimizeCanaryBenchmark | Duration | msec | 60 | 167.303 | 0.028 | 167.267 | 167.457 |
| System.Numerics.Tests.Perf_Vector4.LengthSquaredBenchmark | Duration | msec | 72 | 139.946 | 1.153 | 139.434 | 146.619 |
| System.Numerics.Tests.Perf_Vector4.LengthSquaredJitOptimizeCanaryBenchmark | Duration | msec | 60 | 167.294 | 0.030 | 167.256 | 167.426 |
| System.Numerics.Tests.Perf_Vector4.MultiplyFunctionBenchmark | Duration | msec | 100 | 83.720 | 0.490 | 83.619 | 88.293 |
| System.Numerics.Tests.Perf_Vector4.MultiplyOperatorBenchmark | Duration | msec | 100 | 83.908 | 1.959 | 83.616 | 102.587 |
| System.Numerics.Tests.Perf_Vector4.NormalizeBenchmark | Duration | msec | 8 | 1311.847 | 0.070 | 1311.751 | 1311.921 |
| System.Numerics.Tests.Perf_Vector4.NormalizeJitOptimizeCanaryBenchmark | Duration | msec | 8 | 1426.127 | 4.182 | 1423.842 | 1436.348 |
| System.Numerics.Tests.Perf_Vector4.SquareRootBenchmark | Duration | msec | 45 | 224.741 | 5.425 | 223.119 | 259.937 |
| System.Numerics.Tests.Perf_Vector4.SquareRootJitOptimizeCanaryBenchmark | Duration | msec | 28 | 362.996 | 0.189 | 362.704 | 363.471 |
| System.Numerics.Tests.Perf_Vector4.SubtractFunctionBenchmark | Duration | msec | 100 | 83.822 | 0.062 | 83.783 | 84.407 |
| System.Numerics.Tests.Perf_Vector4.SubtractOperatorBenchmark | Duration | msec | 100 | 83.730 | 0.049 | 83.630 | 83.895 |

CC. @fiigii, @CarolEidt, @eerhardt

@danmosemsft, what is this issue tracking at this point? Someone doing an investigation across all of our code to find places where this would be useful? Or can this be closed?

Let's separately track any individual opportunities we see.

Was this page helpful?
0 / 5 - 0 ratings