C#:是否有任何标准编译标志可以让我检测我是针对 x86 还是 x64 进行编译?

发布于 2024-09-29 23:57:42 字数 469 浏览 0 评论 0原文

我在计数器上使用原子操作,并且我关心性能。我知道在 64 位平台上递增一个 long 可以一次性完成,而在 32 位平台上它需要两条指令

我有这样的代码片段

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

但是我在我的代码中没有定义 X64 常量项目的配置。我想知道是否有一种方法可以通过 #if 语句确定我们是否正在针对 x64 进行编译。当我实现循环队列时,我希望在 x86 上运行时强制其大小达到 40 亿个元素,但在 x64 上运行时我可能会喜欢将其大小解锁为 long.MaxValue。我知道在现代处理器上,一两条指令并不真正关心,但我仍然好奇是否可以通过代码检测配置,而无需重新定义指定此类常量的 x64 配置文件。

谢谢。

I'm using atomic operations on counters, and I care about performance. I know that on the 64-bit platform incrementing a long can be done in one shot, instead it requires two instructions in 32-bit platforms

I have such a code fragment

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

But I define no X64 constant in my project's configuration. I wonder if there is a way to determine via #if statements if we are compiling for the x64 or not. When I implement a circular queue, I want to force its size up to 4 billions elements when running on x86, but I may appreciate unlocking its size to long.MaxValue when on x64. I know that on modern processors one or two instructions don't really care, but it's still my curiosity to know if I can detect the configuration via code without redefining an x64 profile with such constant specified.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小嗷兮 2024-10-06 23:57:42

实现此目的的一种方法是使用 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);
}

我看不出有任何理由不在所有情况下使用静态属性,因为它是最简单的。

One way to do this is to use System.IntPtr, which already abstracts the "bitness" of the assembly.

Note that by default, the C# compiler compiles for "anycpu" which means that the bitness of the assembly at runtime is determined by the bitness of the process into which it is loaded. For executable assemblies, this is x86 for 32 bit OS and x64 for 64 bit OS.

There are 3 equivalent ways to get the size of 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);
}

I can't see any reason not to use the static property for all cases, since it is easiest.

风筝在阴天搁浅。 2024-10-06 23:57:42

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

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

No there is no such preprocessor flag available in part because C# doesn't really have a notion of compiling for different platforms. The command line option /platform doesn`t change the way the C# code is compiled at all but instead sets a flag on the resulting CLR binary restricting the type of processor the binary can run on.

In general though if you want to vary the size of a number value between 4 and 8 bytes based on a 32 and 64 bit platform, the bestn approach is to wrap the System.IntPtr type. This type will vary in this manner and your type can effectively use it as a backing store.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文