Search Unity

Resolved Unity SIMD Acceleration

Discussion in 'Scripting Dev Blitz Day 2023 - Q&A' started by stonstad, Feb 22, 2023.

  1. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    659
  2. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Have a look at the (new) Unity Math-library.
    Unity.Mathematics | Package Manager UI website (unity3d.com)
    Designed for ECS/Jobs, it's (supposed to be?) SIMD-accelerated.

    Edit: Correction.. It's sort of 'IL'. Burst-compiling using the lib will provide/create the proper SIMD-accelerated types.
     
    stonstad likes this.
  3. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    659
    Thank you!

    I'd like to refine my question. Will (or can) this support be added to Transform, Matrix and Vector3? If it can't (or shouldn't be), what is the thinking behind that?
     
    DevDunk likes this.
  4. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    417
    Hello stonstad,

    Today, the only SIMD acceleration we have is going through Burst. Unity.Mathematics is SIMD accelerated as well as the Burst HW SIMD Intrinsics.

    We are working on moving away from Mono and bring support for CoreCLR, and so this will bring support for .NET SIMD types.

    We hope also to bring that support back to Burst, as well as making Unity.Mathematics / Burst Intrinsics compatible/accelerated by CoreCLR.

    I think that already today, many of these types (at least e.g Matrix for sure), has many implementations that are actually in C++ and are already using SIMD.

    By moving to CoreCLR, we might be able to move away from C++ and implement this in C#. There is no concrete plan to do that work, but it should be definitely possible to bring it once we have CoreCLR up and running.
     
  5. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    659
    Awesome, thank you!
     
    dannyalgorithmic likes this.
  6. dannyalgorithmic

    dannyalgorithmic

    Joined:
    Jul 22, 2018
    Posts:
    100
    xoofx and melvyn may, man. These guys are on F***ing fire.
     
  7. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    228
    Hello @xoofx , I also have a question about SIMD in Unity.


    Does this mean that `System.Numerics.Vector` is not(yet) optimized when built in IL2CPP?

    `System.Numerics.Vector` has some public methods like Length() or Distance(). It's implementation contains a call to `Vector.IsHardwareAccelerated` to check if the system supports SIMD or not.

    Code (CSharp):
    1.  // System.Numerics.Vertor2.cs
    2. /// <summary>
    3. /// Returns the length of the vector.
    4. /// </summary>
    5. /// <returns>The vector's length.</returns>
    6. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    7. public float Length()
    8. {
    9.     if (Vector.IsHardwareAccelerated)
    10.     {
    11.         float ls = Vector2.Dot(this, this);
    12.         return (float)Math.Sqrt(ls);
    13.     }
    14.     else
    15.     {
    16.         float ls = X * X + Y * Y;
    17.         return (float)Math.Sqrt((double)ls);
    18.     }
    19. }
    When it is built with IL2CPP(iOS Xcode project, for example), the following code is generated:
    Code (CSharp):
    1. // System.Single System.Numerics.Vector2::Length()
    2. IL2CPP_EXTERN_C IL2CPP_METHOD_ATTR float Vector2_Length_mC99CCF8D33432D4C3392E1390C7605A053251E18 (Vector2_tD99316096CAA530734E8AEB77A0353568D6DC575* __this, const RuntimeMethod* method)
    3. {
    4.     static bool s_Il2CppMethodInitialized;
    5.     if (!s_Il2CppMethodInitialized)
    6.     {
    7.         il2cpp_codegen_initialize_runtime_metadata((uintptr_t*)&MathF_t54810B9E7503B5BD0850A3D6E6336922E1553C52_il2cpp_TypeInfo_var);
    8.         s_Il2CppMethodInitialized = true;
    9.     }
    10.     {
    11.         bool L_0;
    12.         L_0 = Vector_get_IsHardwareAccelerated_m783509258751EBED64CBD9F387EC1BB4A15088AA(NULL);
    13.         if (!L_0)
    14.         {
    15.             goto IL_001e;
    16.         }
    17.     }
    18.     {
    19.         Vector2_tD99316096CAA530734E8AEB77A0353568D6DC575 L_1 = (*(Vector2_tD99316096CAA530734E8AEB77A0353568D6DC575*)__this);
    20.         Vector2_tD99316096CAA530734E8AEB77A0353568D6DC575 L_2 = (*(Vector2_tD99316096CAA530734E8AEB77A0353568D6DC575*)__this);
    21.         float L_3;
    22.         L_3 = Vector2_Dot_m3DBD983D4FEBCC0FE4E598FE56C6DDFC51C0250B_inline(L_1, L_2, NULL);
    23.         il2cpp_codegen_runtime_class_init_inline(MathF_t54810B9E7503B5BD0850A3D6E6336922E1553C52_il2cpp_TypeInfo_var);
    24.         float L_4;
    25.         L_4 = sqrtf(L_3);
    26.         return L_4;
    27.     }
    28. IL_001e:
    29.     {
    30.         float L_5 = __this->___X_0;
    31.         float L_6 = __this->___X_0;
    32.         float L_7 = __this->___Y_1;
    33.         float L_8 = __this->___Y_1;
    34.         il2cpp_codegen_runtime_class_init_inline(MathF_t54810B9E7503B5BD0850A3D6E6336922E1553C52_il2cpp_TypeInfo_var);
    35.         float L_9;
    36.         L_9 = sqrtf(((float)il2cpp_codegen_add(((float)il2cpp_codegen_multiply(L_5, L_6)), ((float)il2cpp_codegen_multiply(L_7, L_8)))));
    37.         return L_9;
    38.     }
    39. }

    I expected that those call to

    Code (CSharp):
    1.         L_0 = Vector_get_IsHardwareAccelerated_m783509258751EBED64CBD9F387EC1BB4A15088AA(NULL);
    2.         if (!L_0)
    3.         {
    4.             goto IL_001e;
    5.         }
    would be optimized depending on the platform I'm targeting, but it wasn't, I can confirm that Vector.IsHardwareAccelerated was called with Xcode Instruments.