Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# &引用;“不精确故障”;还有SIMD_C#_Cil - Fatal编程技术网

C# &引用;“不精确故障”;还有SIMD

C# &引用;“不精确故障”;还有SIMD,c#,cil,C#,Cil,我正在看报纸。在附录中,它谈到了“不精确错误”,这意味着用户可以指定空引用异常等的确切顺序可以放宽。附录讨论了JITer可以使用的各种方法来提高性能 一个特别的小节吸引了我的眼球: F.5.2对循环进行矢量化 对循环进行矢量化通常需要知道 两件事: 循环迭代是独立的 循环迭代的次数是已知的 在一种对可能出现故障的检查放松的方法中,第1部分是 通常为假,因为故障的可能性会导致控制 从每个循环迭代到后续循环迭代的依赖性。在里面 作为一种宽松的方法,可以忽略这些控件依赖关系。大多数 在某些情况下,宽松

我正在看报纸。在附录中,它谈到了“不精确错误”,这意味着用户可以指定空引用异常等的确切顺序可以放宽。附录讨论了JITer可以使用的各种方法来提高性能

一个特别的小节吸引了我的眼球:

F.5.2对循环进行矢量化

对循环进行矢量化通常需要知道 两件事:

  • 循环迭代是独立的

  • 循环迭代的次数是已知的

  • 在一种对可能出现故障的检查放松的方法中,第1部分是 通常为假,因为故障的可能性会导致控制 从每个循环迭代到后续循环迭代的依赖性。在里面 作为一种宽松的方法,可以忽略这些控件依赖关系。大多数 在某些情况下,宽松的方法通过允许检查被简化,从而简化了矢量化 吊出一个环。尽管如此,即使不需要进行此类吊装 可能的情况是,忽略错误隐含的交叉迭代依赖关系可能会 对于“短矢量”SIMD硬件的矢量化至关重要,例如 IA-32 SSE或PowerPC Altivec

    例如,考虑这个循环:

    for (k = 0; k < n; k++) {
       x[k] = x[k] + y[k] * s[k].a;
    }
    
    (k=0;k{ x[k]=x[k]+y[k]*s[k].a; } 其中s是一个引用数组。检查是否存在空引用 即使在轻松的环境中,也无法从循环中提升。但是 relaxed允许成功应用“展开和卡住”。这个 循环可以展开4倍以创建聚合迭代, 并将检查提升到每个聚合迭代的顶部

    也就是说,这意味着,如果使用这些松弛故障,JITer可以自动将循环转换为SIMD操作。规范建议您可以使用System.Runtime.CompilerServices.CompileationRelaxations枚举设置这些松弛故障。但在实际的C#中,enum只有NoStringInterning选项,没有任何其他选项。我已尝试将System.Runtime.CompilerServices.CompileationRelaxationsAttribute设置为从中提取的一些int代码,但在生成的x86程序集中没有任何区别

    据我所知,官方的微软JIT并没有实现这一点。我知道Mono有名称空间,所以我猜它也没有实现这个

    所以我很好奇,我是否遗漏了关于附录(以及第12.6.4节“优化”,也谈到了这一点)的一些历史。如果两个主要供应商都没有实际实施,为什么会出现在标准中?微软是否有计划在未来进行这项工作

    所以我很好奇,我是否遗漏了关于附录(以及第12.6.4节“优化”,也谈到了这一点)的一些历史。如果两个主要供应商都没有实际实施,为什么会出现在标准中?微软是否有计划在未来进行这项工作

    我怀疑这是为了提供一个选项,允许在某个时候实现它,而不破坏实现或需要更改规范

    但在实际的C#中,enum只有NoStringInterning选项,没有任何其他选项

    这是因为,
    NoStringInterning
    是目前唯一受支持的选项。由于C#中的enum是可扩展的(它只是一个基本的整数类型),因此运行时的未来版本可以很容易地扩展以支持其他选项


    请注意,微软在这方面还有一些改进的地方。

    这是必须编写CLI规范的人的负担,他还不知道在抖动中实际实现这一点是否可行。这会在以后发生


    SIMD是一个问题,它有一个相当困难的变量对齐要求。至少在写入x86抖动时,尝试在错误对齐的变量上应用SIMD指令会产生硬总线故障。不太确定x64抖动写入时的技术水平,但今天它仍然非常昂贵。x86抖动不能比4字节对齐更好,x64不能比8字节对齐更好。它可能需要下一代128位内核来获得16字节的对齐,才能真正使其有效。我不会为此屏住呼吸:)

    是的,对齐要求很痛苦。但无论如何,SIMD对于阵列上的for循环都是有意义的。我不认为专门对齐16字节数组会有那么大的困难。当然,这不能处理所有的情况,但我认为这对于最常见的情况是有意义的。但我不是JIT设计师。在阅读CIL规范时,JITer必须担心一些非常棘手的边缘情况,这些情况几乎不重要,除非它们确实如此:)数组是托管语言中的托管对象。所以,是的,对齐要求是一种痛苦。当前的GC堆实现无法提供比本机指针大小更好的对齐方式(按设计)。改变这一点要么是非常痛苦的,要么是非常浪费的。主要的浪费方面是如果分配大小低于某个阈值,对吗?因此,我不觉得仅在大型分配中添加对齐要求(通过扩大分配大小请求或其他方式)会很困难。事后检查对齐(指针地址的低位4位是否为0?)很容易,如果必须的话,可以基于此打开/关闭SIMD优化。主要的问题是元信息是否存储在分配的顶部字节中,或者类似的东西。不,垃圾收集器在压缩堆时移动对象。它之前的路线不是之后的路线。处理这件事是最痛苦的。除非堆实现始终确保16字节对齐。这是浪费的一部分。是的,但它仍然需要分配它要将对象移动到的位置,