gpt4 book ai didi

c# - C# 中的 [Intrinsic] 属性有什么作用?

转载 作者:太空狗 更新时间:2023-10-29 19:40:18 27 4
gpt4 key购买 nike

在 Google 上快速搜索“instrinsic attribute c#”只会返回关于其他属性的文章,例如 [Serializable] .显然,这些被称为“内在属性”。

但是,C# 中还有一个属性,它本身称为 [Intrinsic]我试图弄清楚它到底是什么以及它是如何工作的。它在 common attributes 上不存在.NET 文档的页面,或据我所知文档中的任何其他地方。

此属性在 .NET Core 内部的多个地方使用,例如,在 System.Numerics.Vectors 中。文件夹,例如 Vector2_Intrinsics.cs .代码片段:

[Intrinsic]
public Vector2(float x, float y)
{
X = x;
Y = y;
}

最佳答案

这是我在通过 dotnet/corefx 进行非常有限的搜索后设法找到的内容github 上的存储库。
[Intrinsic]标记可能被 JIT 替换/优化的方法、属性和字段。源代码注释说了类似的话( IntrinsicAttribute.cs ):

Calls to methods or references to fields marked with this attribute may be replaced at some call sites with jit intrinsic expansions. Types marked with this attribute may be specially treated by the runtime/compiler.



目的

核心开发者, [Intrinsic]至少有两个目的:
  • 它通知开发者标记的字段、方法或属性的代码可以被 VM 替换。因此,如果代码发生变化,则可能应该在两个地方都引入更改;
  • 它用作 JIT 优化器的标志,以快速识别可以优化的方法。

  • 举个粗略的例子:JIT-optimizer 可以代替 Enum.HasFlag在某些情况下进行简单的按位比较,而在其他情况下则不然。为此,它需要将方法标识为 Enum.HasFlag ,检查一些条件并将其替换为更优化的实现。优化器可以通过名称识别方法,但出于性能原因,最好在执行字符串比较之前通过简单的标志过滤掉方法。

    用法

    该属性仅与核心开发人员相关。您应该只在内部类中使用它,并且仅在您想为其提出非常具体的 JIT 级优化的情况下使用它。 [Intrinsic]几乎仅限于一小组广泛使用的 .Net 类,由于某种原因,无法通过其他方式进行优化。

    from the comments: I'm planning to propose a Color struct for .NET Core which needs to behave similarly to other built-in types for consistency.



    您可能不应该使用 [Intrinsic]在你最初的提议中。过了之后就可以考虑优化了,如果 Color时有一个有效的场景将受益于低级优化,您可以建议使用 [Intrinsic]关于它的一些方法或属性。

    这个怎么运作

    方法如下 [Intrinsic]目前在核心中使用:
  • 它被定义为一个众所周知的属性( wellknownattributes.h ):
    case WellKnownAttribute::Intrinsic:
    return "System.Runtime.CompilerServices.IntrinsicAttribute";
  • VM 解析它并设置 IsJitIntrinsic方法的标志为真( methodtablebuilder.cpp ):
    if (bmtProp->fIsHardwareIntrinsic || (S_OK == GetCustomAttribute(pMethod->GetMethodSignature().GetToken(),
    WellKnownAttribute::Intrinsic,
    NULL,
    NULL)))
    {
    pNewMD->SetIsJitIntrinsic();
    }
  • 此标志用于在方法属性( jitinterface.cpp )中设置另一个标志:
    if (pMD->IsJitIntrinsic())
    result |= CORINFO_FLG_JIT_INTRINSIC;
  • 此标志稍后用于过滤掉明显不是内在的方法( importer.cpp ):
    if ((mflags & (CORINFO_FLG_INTRINSIC | CORINFO_FLG_JIT_INTRINSIC)) != 0)
    {
    const bool isTail = canTailCall && (tailCall != 0);

    call = impIntrinsic(newobjThis, clsHnd, methHnd, sig, mflags, pResolvedToken->token, readonlyCall, isTail,
    pConstrainedResolvedToken, callInfo->thisTransform, &intrinsicID, &isSpecialIntrinsic);
  • impIntrinsic然后拨打 lookupNamedIntrinsic 识别(主要是通过名称)真正(不仅仅是可能)应该优化的方法;
  • 毕竟,importer可以根据方法进行优化。例如,优化 Enum.HasFlag ( importer.cpp ):
     case NI_System_Enum_HasFlag:
    {
    GenTree* thisOp = impStackTop(1).val;
    GenTree* flagOp = impStackTop(0).val;
    GenTree* optTree = gtOptimizeEnumHasFlag(thisOp, flagOp);

    if (optTree != nullptr)
    {
    // Optimization successful. Pop the stack for real.
    impPopStack();
    impPopStack();
    retNode = optTree;
    }
    else
    {
    // Retry optimizing this during morph.
    isSpecial = true;
    }

    break;
    }

  • 免责声明:据我所知,属性的行为在任何地方都没有正确记录,因此可能会发生变化。以上描述仅与master中的代码相关,这部分core正在积极开发中,整个流程可以在以后更改。

    历史

    这是 [Intrinsic] 的简短时间表基于github存储库历史:
  • 2014 年之前的某个时间 [JitIntrisic]属性作为 System.Numerics 的一部分引入以支持新的处理器指令为目标(参见 How does JitIntrinsicAttribute affect code generation?)。
  • 2016年6月6日,Chris McKinsey开了一个问题 #5626. "Optimize enum1.HasFlag(enum2) into inline bittest without boxing allocations when types are the same" .当时,Enum.HasFlag有一个众所周知的性能问题(见 What is it that makes Enum.HasFlag so slow?)。
  • 在处理此问题时 Andy Ayers建议引入通用机制来引入 JIT 内在函数 ( Issue #13813: Add more flexible method for specifying jit instrinsics )
  • 这导致了两个拉取请求:New jit intrinsic support介绍了[Intrinsic]的通用力学和 JIT: optimize Enum.HasFlagEnum.HasFlag 实现了它.我建议通读它们,因为它们非常说明 [Intrinsic] 带来的变化。 .
  • 后来在讨论搬家时 Vector classes to the CoreLib有人建议[JitIntrinsic]未在任何地方使用,应更换/移除:

  • @jkotas: We should not need the JitIntrinsicAttribute. As far as I know, this attribute was future proofing, never used for anything real. We should delete it, and use the IntrinsicAttribute from CoreLib instead.


  • 及时,[JitIntrinsic]已被移除并替换为 [Intrinsic] ( Replace JitIntrinsicAttribute with IntrinsicAttribute )。这就是这个属性在 Vector2 中的来源。 .
  • 关于c# - C# 中的 [Intrinsic] 属性有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56388664/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com