如何使用C#将变量存储在机器寄存器中?

时间:2014-10-03 20:23:38

标签: c#

我在MSDN上引用并找到register关键字,但它只在C ++中使用。

语法:

register int x = 0;

你能用C#告诉我怎么做吗?

3 个答案:

答案 0 :(得分:3)

在C#中无法做到这一点。 C#编译为MSIL,然后由JIT编译为本机代码。

JIT将决定变量是否会进入寄存器。你不应该担心这个。

由于MSIL应该在不同的体系结构上运行,因此在语言中包含这样的功能是没有多大意义的。不同的体系结构具有不同数量的寄存器,其可以具有不同的大小。这就是JIT优化这一目标的原因。

答案 1 :(得分:1)

  

通过使用关键字? No

使用非托管代码,您当然可以...我的意思是,您确实不想...但是您可以:)

它在极限优化中很有用,在这种情况下,您可以确定自己可以做得比JIT Compiler更好。但是,在这种情况下,无论如何,您可能应该直接看待不受管理的C。因此,我强烈建议您这样做。

让我们假设你做不到,这绝对是肯定的,必须从C#完成

C#已编译为MSIL,这使这些选择不再为您所用。它实际上也做得很好,因此,实际上很少需要手动优化。但是,C#是托管语言,因此您必须进入非托管部分才能实现。

有几种方法,有和没有反射-都使用内联和外部。

首先,您可以将CASM或其他一些非托管语言中的那个小的快速段编译为DLL,并以与您所使用的几乎相同的方式从C#对其进行非托管调用调用WinAPI函数...请注意调用约定,其中有几个,并且每个给caller / callee带来了稍微不同的负担...例如,就参数如何通过,然后谁清除了堆栈。

或者,对于任何必须超快的例程,可以使用fasmNET或类似方法来包含内联汇编。 fast可以将c#中的Assembler字符串(在运行时)编译为一个内存块,然后可以从c#中对其进行不受管理的调用。在线存在许多示例。

或者,您可以在外部编译所需的指令,自己将其提供为字节数组,然后以与上述相同的方式将字节数组作为代码调用,但无需运行时编译步骤。

使用内联IL也可以使用许多技巧,这些技巧可以帮助您在不涉及JIT编译器的情况下微调代码,这些技巧可能对您有用,也可能对您不起作用,这取决于您的项目。自定义IL部分可以用内联IL和动态IL来完成,并且可以使您对c#应用程序的运行方式有更多的控制。

根据需要在托管和非托管之间来回切换的频率,还可以从代码中创建一个单独的应用程序域,并将非托管代码加载到该域中,这可以帮助您将托管/非托管代码分开关注,从而避免了任何昂贵的来回切换。

但是...

我不会给出代码,因为您如何执行它很大程度上取决于您要完成的工作。这不是那种只需要将代码片段粘贴到项目中的事情-您需要研究各种方法,了解它们的开销和缺点,然后谨慎,明智和尽职地实施它们。

就个人而言,我建议学习C并卸载诸如外部服务之类的对计算很重要的任务。这具有允许您使用处理器亲和力以达到最佳效果的附加优势。它还可以让您为前端写干净,正常,明智的C#

但是请相信我,如果您的代码太慢,并且您认为对某些变量使用寄存器会加快处理速度……好吧……95%的时间绝对不会。 C#在后​​台进行了大量工作,以尽可能有效地扭曲CPU资源……如果您介入并从中抢夺一些寄存器的控制权,通常最终会产生总体上较差的最佳代码。

因此,如果迫切希望找到最佳策略,我建议您将该小任务卸载到单独的C程序或服务中,然后使用C#抛出问题并收集输出。加上亲和力,这可以大大提高速度。如果需要,也可以在托管代码和非托管代码之间设置共享内存-尽管这需要进行大量的前瞻性计划,可能需要使用良好的商业调试器,但肯定不适合初学者。

请注意,无论您采用哪种方式,便携性都会受到不利影响。

重新评估您是否真的需要这样做。就算法本身而言,可以从C#内进行许多更明智和更有成效的优化,在深入研究硬件之前,应进行充分的探索。

答案 2 :(得分:0)

你不能。 在IL中没有任何真正有用的寄存器,并且不能保证目标机器将具有寄存器。 JIT或Ahead-of-time编译器将为您做出决定。