4

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

一个引起我注意的特定小节:

F.5.2 向量化循环

向量化循环通常需要知道两件事:

  1. 循环迭代是独立的

  2. 循环迭代的次数是已知的。

在对可能出现故障的检查放宽的方法中,第 1 部分经常是错误的,因为出现故障的可能性会导致从每个循环迭代到后续循环迭代的控制依赖性。在宽松的方法中,可以忽略这些控制依赖性。在大多数情况下,宽松的方法通过允许将检查提升到循环之外来简化矢量化。然而,即使这种提升是不可能的,忽略故障隐含的交叉迭代依赖性对于“短向量”SIMD 硬件(如 IA-32 SSE 或 PowerPC Altivec)的向量化可能是至关重要的。

例如,考虑这个循环:

for (k = 0; k < n; k++) {
   x[k] = x[k] + y[k] * s[k].a;
}

其中 s 是引用数组。即使在宽松的上下文中,对空引用的检查也不能脱离循环。但是轻松确实允许成功应用“展开和卡纸”。循环可以展开 4 倍以创建聚合迭代,并将检查提升到每个聚合迭代的顶部。

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

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

所以我很好奇我是否缺少关于该附录(以及第 12.6.4 节“优化”,也谈到了这一点)的一些历史记录。如果两个主要供应商都没有真正实施它,为什么它在标准中?微软是否有计划在未来开展这项工作?

4

2 回答 2

3

所以我很好奇我是否缺少关于该附录(以及第 12.6.4 节“优化”,也谈到了这一点)的一些历史记录。如果两个主要供应商都没有真正实施它,为什么它在标准中?微软是否有计划在未来开展这项工作?

我怀疑这是专门为了提供允许在某些时候实现它而不破坏实现或需要更改规范的选项。

但在实际的 C# 中,枚举只有 NoStringInterning 选项,没有其他选项

这是因为这NoStringInterning是目前唯一受支持的选项。由于 C# 中的枚举是可扩展的(它只是一个底层整数类型),因此可以轻松扩展运行时的未来版本以支持其他选项。

请注意,在 VS UserVoice站点上有一些建议供 Microsoft 在这方面进行改进。

于 2012-04-05T18:46:06.130 回答
1

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

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

于 2012-04-05T19:08:23.210 回答