是否可以在C#中使用分支预测提示?

例如,我知道它是为gcc定义的,并在Linux内核中用作:

#define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) 

如果在C#中没有这样的东西是可能的,那么手动重新排序if语句的最佳选择是什么,最可能的情况是第一个? 有没有其他方法可以根据这种类型的外部知识进行优化?

在相关的说明中,CLR知道如何识别保护条款并假设将采用备用分支,使得这种优化不适合用于保护条款,是否正确?

(请注意,我意识到这可能是微观优化;我只对学术目的感兴趣。)

简答:没有。

更长的答案:在大多数情况下,你并不需要。 您可以通过更改语句中的逻辑提供提示。 使用性能工具更容易,例如内置于更高(也更昂贵)的Visual Studio版本的工具,因为您可以捕获错误预测的分支计数器。 我意识到这是出于学术目的,但我们很高兴知道JITer 非常擅长为您优化代码。 作为一个例子( 通过C#从CLR中逐字逐句采用)

这段代码:

 public static void Main() { Int32[] a = new Int32[5]; for(Int32 index = 0; index < a.Length; index++) { // Do something with a[index] } } 

可能看起来效率低下,因为a.Length是一个属性,正如我们在C#中所知,属性实际上是一组两个方法(在这种情况下为get_Lengthset_Length )。 但是,JIT知道它是一个属性,并将长度存储在本地变量中,或者内联方法,以防止开销。

...一些开发人员低估了JIT编译器的能力,并试图编写“聪明的代码”以试图帮助JIT编译器。 但是,您提出的任何聪明尝试几乎肯定会对性能产生负面影响,并使您的代码难以阅读,从而降低其可维护性。

除此之外,它实际上更进一步,并且在循环外部而不是在循环内部进行边界检查,这会降低性能。

我意识到它与你的问题没有什么关系,但我想我想要的是,像这样的微优化在C#中并没有真正帮助你,因为JIT通常做得更好,因为它完全是为此而设计的。 (有趣的是,x86 JIT编译器比x64编译器执行更积极的优化)

本文解释了.NET 3.5 SP1中添加的一些优化,其中包括改进分支分支以改进预测和缓存局部性。

所有这些,如果你想阅读一本关于编译器生成和CLR性能的好书,我推荐我从上面引用的书,CLR通过C#。

编辑:我应该提一下,如果目前可以在.NET中使用,您可以在EMCA-335标准或工作草案中找到相关信息。 没有标准可以支持这一点,并且在像IlDasm或CFF Explorer这样的内容中查看元数据时,没有显示任何可以提示分支预测的特殊元数据的迹象。