Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的[固有]属性做什么?_C#_.net_.net Core_Intrinsics - Fatal编程技术网

C#中的[固有]属性做什么?

C#中的[固有]属性做什么?,c#,.net,.net-core,intrinsics,C#,.net,.net Core,Intrinsics,在谷歌上快速搜索“instrinicattributec#”,只会返回有关其他属性的文章,例如[Serializable]。显然,这些被称为“内在属性” 然而,C#中还有一个属性,它本身被称为[内在],我正试图弄清楚它到底是什么以及它是如何工作的。它不存在于.NET文档的页面上,也不存在于我所能看到的文档中的任何其他地方 此属性在.NET Core内部的多个位置使用,例如,在文件夹中,例如。代码段: [固有] 公共向量2(浮点x,浮点y) { X=X; Y=Y; } 说明: 使用 Intrins

在谷歌上快速搜索“instrinicattributec#”,只会返回有关其他属性的文章,例如
[Serializable]
。显然,这些被称为“内在属性”

然而,C#中还有一个属性,它本身被称为
[内在]
,我正试图弄清楚它到底是什么以及它是如何工作的。它不存在于.NET文档的页面上,也不存在于我所能看到的文档中的任何其他地方

此属性在.NET Core内部的多个位置使用,例如,在文件夹中,例如。代码段:

[固有]
公共向量2(浮点x,浮点y)
{
X=X;
Y=Y;
}
说明:

使用 IntrinsicatAttribute自定义属性。如果使用 属性,编译器不知道 给定类型的实现将在运行时出现。 标记为内在类型的方法可以将方法声明为 extern,在这种情况下,假定实现在 运行时

来源:MSIL到JavaScript编译器,第4.4.1.1节

链接:


一般来说,我建议不要在意它,也不要将它用于您自己的类。

以下是我在github上的存储库中进行了非常有限的搜索后找到的内容

[固有]
标记可能被JIT替换/优化的方法、属性和字段。源代码注释说明了类似的内容():

在某些调用站点上,对方法的调用或对标记有此属性的字段的引用可能会被jit内部扩展替换。运行时/编译器可能会特别处理标记有此属性的类型

目的 对于核心开发人员,
[固有]
至少有两个用途:

  • 它通知开发人员标记的字段、方法或属性的代码可以被VM替换。因此,如果代码发生了变化,那么可能应该在这两个地方引入变化
  • 它被用作JIT优化器的标志,以快速识别可能被优化的方法
举一个粗略的例子:JIT优化器可以在某些情况下用简单的按位比较替换
Enum.HasFlag
,而在其他情况下则不能。为此,需要将方法标识为
Enum.HasFlag
,检查一些条件并用更优化的实现替换它。优化器可以通过名称识别方法,但是,出于性能原因,最好在执行字符串比较之前通过简单的标志筛选出方法

用法 该属性仅与核心开发人员相关。您应该只在内部类中使用它,并且只在您想要为它提出非常具体的JIT级别优化的情况下使用它<代码>[固有]非常局限于一小部分广泛使用的.Net类,由于某些原因,这些类无法通过其他方法进行优化

从评论中可以看出:我计划为.NETCore提出一个颜色结构,它需要与其他内置类型的行为类似,以保持一致性

您可能不应该在初始提案中使用
[固有]
。在它通过之后,您可以考虑优化,如果您有一个有效的场景,
Color
将从低级优化中受益,那么您可以建议对它的一些方法或属性使用
[固有]

工作原理 以下是当前在core中如何使用
[固有]

  • 它被定义为一个众所周知的属性():

  • VM对其进行解析,并将方法()的
    isjit
    标志设置为true:

  • 此标志用于在方法属性()中设置另一个标志:

  • 此标志稍后用于筛选出明显不是内在()的方法:

  • impinfrant
    然后调用以确定(主要是通过名称)真正(而不仅仅是潜在)应该优化的方法

  • 在所有这些之后,
    importer
    可以基于方法执行优化。例如,
    Enum.HasFlag
    ()的优化:

免责声明:据我所知,该属性的行为在任何地方都没有适当的文档记录,因此可能会发生更改。以上描述仅与master中当前的代码相关,核心的这一部分正在积极开发,未来整个过程可以更改

历史 以下是基于github存储库历史的
[内在]
的简短时间线:

  • 在2014年之前的某个时候,
    [JitIntrisic]
    属性作为
    系统的一部分引入。数字
    的目标是支持新的处理器指令(请参阅)

  • 2016年6月6日,发行。当时,
    Enum.HasFlag
    存在众所周知的性能问题(请参阅)

  • 在处理这个问题时,我们建议引入一种通用机制来引入JIT本质()

  • 这导致了两个pull请求:介绍了
    [内在]
    的一般机制,并为
    Enum.HasFlag
    实现了它。我建议仔细阅读这两篇文章,因为它们非常能说明
    [内在]
    所带来的变化

  • 后来,在关于移动的讨论中,有人建议,
    [jit]
    不在任何地方使用,应该替换/删除:

:我们不应该需要jitinrinsication属性。据我所知,这个属性是未来的证明,从未用于任何真实的东西。我们应该删除它,并改用CoreLib中的intrinsicatAttribute

  • 很快,
    [jitInquired]
    被删除并替换为
    [Inquired]
    ()。这就是为什么这个属性出现在
    Vector2

此属性的源代码可用
case WellKnownAttribute::Intrinsic:
    return "System.Runtime.CompilerServices.IntrinsicAttribute";  
if (bmtProp->fIsHardwareIntrinsic || (S_OK == GetCustomAttribute(pMethod->GetMethodSignature().GetToken(),
                                            WellKnownAttribute::Intrinsic,
                                            NULL,
                                            NULL)))
{
    pNewMD->SetIsJitIntrinsic();
}          
if (pMD->IsJitIntrinsic())
    result |= CORINFO_FLG_JIT_INTRINSIC;
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);
 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;
    }