2010-10-29 78 views
2

我在柜台上使用原子操作,我关心性能。我知道,64位平台递增long可以一次性完成,对代替它需要在32位平台上的两个指令C#:是否有任何标准的编译标志,允许我检测是否编译为x86或x64?

我有这样的代码片段

#if X64 
using COUNTER_TYPE = System.Int64; 
#else 
using COUNTER_TYPE = System.Int32; 
#endif 

但我没有定义X64在我的项目配置中不变。我想知道是否有一种方法可以通过#if语句来确定是否编译x64。当我实现一个循环队列时,我想在x86上运行它的大小高达40亿个元素,但是我可能会感激在x64上将其大小解锁为long.MaxValue。我知道,在现代处理器上,一条或两条指令并不真正关心,但我仍然很想知道是否可以通过代码检测配置,而无需使用指定的常量重新定义x64配置文件。

谢谢。

+2

这需要首先进行健全性检查。尝试在x86上实际填充40亿个项目的循环队列。现在在x64上再次尝试。 – 2010-10-29 18:08:51

回答

2

这样做的一种方法是使用System.IntPtr,它已经提取了程序集的“位”。

请注意,默认情况下,C#编译器针对“anycpu”进行编译,这意味着程序集在运行时的位数由其加载的进程的位数决定。对于可执行程序集,这是用于32位操作系统的x86和用于64位操作系统的x64。

有3分等价的方法来获得的IntPtr大小:

// Use the static property 
var size = IntPtr.Size; 

// Use Marshal 
var size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)); 

// Use unsafe with sizeof 
unsafe 
{ 
    var size = sizeof(IntPtr); 
} 

我看不出有任何理由不使用静态属性适用于所有情况,因为它是最容易。

+0

这是通过获取sizeof(System.IntPtr)完成的? – Jordan 2013-10-15 18:54:24

+1

'System.IntPtr.Size' – codekaizen 2013-10-15 20:00:46

+1

如果你想要做的只是在运行时(不是在编译时)决定,如果这是64位的,使用'Environment.Is64BitProcess'静态属性。 (在.NET 4.0中(自2010年起)。) – 2013-10-15 21:53:33

2

不,没有这样的预处理器标志可用,部分原因是C#没有真正的编译不同平台的概念。命令行选项/platform不会改变C#代码编译的方式,而是在生成的CLR二进制文件上设置一个标志,以限制二进制文件可以运行的处理器类型。

一般来说,如果您想要根据32位和64位平台更改4到8个字节之间的数字值的大小,bestn方法是将System.IntPtr类型包装起来。这种类型将以这种方式变化,并且您的类型可以有效地将其用作后备存储。