2


0

C#:x86またはx64向けにコンパイルしているかどうかを検出できる標準のコンパイルフラグはありますか?

カウンターでアトミック操作を使用していますが、パフォーマンスが重要です。 64ビットプラットフォームでは、「long」を1回で増分できることを知っていますが、32ビットプラットフォームでは2つの命令が必要です

私はそのようなコードの断片を持っています

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

しかし、プロジェクトの構成ではX64定数を定義していません。 xifをコンパイルするかどうかを#ifステートメントで判断する方法があるのだろうか。 循環キューを実装するとき、x86で実行するときにサイズを最大40億要素に強制したいのですが、x64でサイズを `long.MaxValue`にロック解除する方がいいかもしれません。 最新のプロセッサでは、1つまたは2つの命令はあまり気にしないことを知っていますが、そのような定数が指定されたx64プロファイルを再定義せずにコードで構成を検出できるかどうかを知ることは私の好奇心です。

ありがとうございました。

2 Answer


2


これを行う1つの方法は、 `System.IntPtr`を使用することです。これは既にアセンブリの「ビットネス」を抽象化します。

デフォルトでは、C#コンパイラは「anycpu」用にコンパイルすることに注意してください。つまり、実行時のアセンブリのビット数は、ロード先のプロセスのビット数によって決まります。 実行可能アセンブリの場合、これは32ビットOSの場合はx86、64ビットOSの場合はx64です。

`IntPtr`のサイズを取得する3つの同等の方法があります。

// 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);
}

それが最も簡単なので、すべての場合に静的プロパティを使用しない理由はわかりません。


2


C#には異なるプラットフォーム用にコンパイルするという概念が実際にはないため、そのようなプリプロセッサフ​​ラグは部分的に使用できません。 コマンドラインオプション `/ platform`はC#コードのコンパイル方法をまったく変更しませんが、代わりに結果のCLRバイナリにフラグを設定し、バイナリを実行できるプロセッサのタイプを制限します。

ただし、一般的に、32ビットと64ビットのプラットフォームに基づいて4〜8バイトの数値のサイズを変更する場合、bestnのアプローチは `System.IntPtr`型をラップすることです。 このタイプはこのように変化し、タイプはバッキングストアとして効果的に使用できます。