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