Windows 64ビットバージョンのC/C++プログラミング



/wp 64:コンパイラに潜在的な問題を警告
microsoft_ Visual cとmicrosoft_visual c++_ .Net 2002コンパイラに/wp 64スイッチが追加され、32ビットコードの64ビット互換性の問題をテストできます.コンパイラは、ポインタの切断と不正な変換に関する警告を発行します.32ビットアプリケーションをwindows 64ビットバージョンに移行する前のステップは、このタグを開き、通常のコードコンパイルのようにコードをコンパイルすることです.初めていくつかの間違いがあります.たとえば、次のコードクリップを参照してください.
dword i = 0;
size_t x = 100;

i = x; // c4267: warning c4267: '=' : conversion from 
    // 'size_t' to 'dword', possible loss of data.

32ビットのプラットフォームでは、size_tは32ビットですが、64ビットのプラットフォームではsize_tは64ビットの整数である./wp 64を有効にすると、コンパイラは同様の状況を警告します.
その他の例:
void func(dword context)
{
  char* sz = (char*)context; // c4312: warning c4312: 
                // 'type cast' : conversion 
                // from 'dword' to 'char *' of
                // greater size
  // do something with sz..
}

char* string = "the quick brown fox jumped over the lazy dog.";

func((dword)string); // c4311: warning c4311: 'type cast' :
           // pointer truncation from 'char *' 
           // to 'dword'

これらのエラーを修正したら、32ビットコードをテストしてください.32ビットのコードが予想通りに動作し続けることを確認します.32ビットと64ビットのバイナリファイルは、同じコードライブラリから構築する必要があります.これが前進するwindowsアプリケーションを作成する重要な概念です.最初は、32ビットと64ビットの問題を考慮し、この2つのプラットフォームで実行できるコードをアプリケーションに記述する必要があります.
新しいデータ型
Windows 64ビットバージョンではllp 64データモデルを使用します.これは、標準cタイプintおよびlongが32ビット整数に保たれていることを意味する.データ型size_tはプロセッサ語サイズ(ia 32は32ビット、ia 64は64ビット)にマッピングされ、_int 64は64ビット整数である.32ビットコードの移行を支援すると、上記の操作が完了します.アプリケーションの32ビットバージョンと64バージョンで同じコードライブラリを使用できることを意味します.
標準的なcタイプlongを64ビット整数にマッピングし、intを32ビット整数に保つlp 64というデータモデルもある.このデータモデルはunixプラットフォームでよく見られますが、アプリケーションの32ビットと64ビットバージョンを単一のコードライブラリから同時に作成するのは困難です.ここの一般的なトピックに気づいたかもしれません.32ビットプラットフォームと64ビットプラットフォームの考え方は、単一のコードライブラリから2つのバージョンのアプリケーションを構築できることです.できない場合は、デザインを見直す必要があります.単一のコード・ライブラリを持つことは、特に2つのバージョンをリリースする計画がある場合に大きな勝利です.
マルチステートタイプ
win 32 apiはcのため、多くの場合、整数をポインタまたは逆に変換する必要があります.32ビットのハードウェアでは問題ありません.ポインタのサイズと整数のサイズは同じですが、64ビットのハードウェアではまったく違います.これがマルチステートタイプが現れる理由です.
特定の精度では、固定精度のデータ型を使用できます.プロセッサの語のサイズにかかわらず、それらのサイズは一致しています.これらのタイプの多くは、次の表から分かるように、名前に精度が含まれています.
表1.固定精度のデータ型
を選択します.
定義#テイギ#
dword32
32ビット符号なし整数
dword64
64ビット符号なし整数
int32
32ビット符号付き整数
int64
64ビット符号付き整数
long32
32ビット符号付き整数
long64
64ビット符号付き整数
uint32
符号なしint 32
uint64
符号なしint 64
ulong32
符号なしlong 32
ulong64
符号なしlong 64
また、プロセッサ語のサイズに応じてデータ型の精度が変化する必要がある場合は、ポインタ精度データ型を使用します.これらのタイプは、「マルチステート」データ型とも呼ばれます.これらのタイプは通常_ptr接尾辞は、次の表に示すように終わります.
表2.ポインタ精度のデータ型
を選択します.
定義#テイギ#
dword_ptr
ポインタ精度の符号なし長タイプ
half_ptr
ポインタサイズの半分.1つのポインタと2つの小さなフィールドを含む構造で使用
int_ptr
ポインタ精度の符号付き整数
long_ptr
ポインタ精度の符号長タイプ
size_t
ポインタが参照できる最大バイト数.ポインタにまたがる必要がある範囲全体のカウント
ssize_t
符号付きsize_t
uhalf_ptr
符号なしhalf_ptr
uint_ptr
符号なしint_ptr
ulong_ptr
符号なしlong_ptr
lparam
とlong_ptrは同義語、(wtyes.hで定義)
wparam
とuint_ptrは同義語、(wtyes.hで定義)
パラメータまたはコンテキスト情報を整数パラメータで渡すすべてのwin 32 apiは、これらの新しいタイプを使用するように変更されます.setwindowlong関数とsetwindowlongptr関数は良い例です.
古い方法:
long setwindowlong(
    hwnd hwnd, 
    int nindex, 
    long dwnewlong);

新しいマルチステートメソッド:
long_ptr setwindowlongptr(
      hwnd hwnd, 
      int nindex, 
      long_ptr dwnewlong);

この関数のxxxptrバージョンでは、新しいマルチステートタイプが使用されていることに注意してください.開発者にとって、ウィンドウの追加のデータ領域にポインタを格納することによって、ウィンドウのコンテキスト情報を格納することは一般的です.setwindowlong関数を使用してwindows 32ビットバージョンにポインタを格納するコードは、setwindowlongptrを呼び出すように変更する必要があります.この変更は、ほとんどの変更でマルチステートタイプが使用される必要があるため、非常に簡単で、すぐに完了できます.
また、windowprocとgetqueuedcompletionstatusも良い例です.
lresult callback windowproc(
          hwnd hwnd, 
          uint uimsg, 
          wparam wparam, 
          lparam lparam);

bool getqueuedcompletionstatus(
          handle hcompletionport, 
          lpdword lpnumberofbytes,
          pulong_ptr lpcompletionkey,
          lpoverlapped* lpoverlapped,
          dword dwmilliseconds);

Windowprocはlparamを使用し、後者はマルチステートタイプです.getqueuedcompletionstatus使用ulong_ptr,後者もマルチステートタイプである.これにより、整数のサイズがポインタのサイズと同じであると仮定した既存のコードは、わずかな変更を行っても動作を継続することができる.
コンパイラの新しい最適化モード:pogoとltcg
Microsoftを含むvisual studio_ .Net 2002のコンパイラには、link time code generation(ltcg、whole program optimizationとも呼ばれる)とprofile guided optimization(pogo)の2つの新しい最適化モードが含まれています.コード最適化は、コンパイラが効率的なコードの生産にすべての責任を負うため、itaniumプロセッサではx 86プラットフォームよりも重要です.この2つの最適化モードは、構築回数を増加させ、特にpogo(分析データをキャプチャする必要があるため)の良好なテストスキームを要求する.ltcgは、リンクがモジュール境界にわたって最適化され、より良い埋め込みコードを生成し、カスタム呼び出し規則を使用することによって、リンク段階で実際にコードを生成して、より効率的なバイナリファイルを生成することを可能にする.pogoは、コンパイラが使用モードに基づいて最適化できるようにします.2つのフェーズの構築プロセスが必要です.最初のフェーズでは、バイナリ・ファイルを使用して分析データを収集します.第2段階では、分析データを分析した後、データは最適化を指導するために使用される.
その他のパフォーマンス
現在のコンパイラは、最適化されたコードを生成するのが得意です.itaniumプロセッサでは、コンパイラが非常に多くの仕事を担当しています.itaniumはシーケンスプロセッサであるため、コンパイラは並列に実行できるように最適化(命令の再配置など)を実行する必要があります.同様に,増加した述語レジスタにより,コンパイラは分岐処理の最適化により多くの自由を得た.述語レジスタを使用すると、コンパイラはブランチを完全に除去し、命令の述語フィールドを使用して、実際に命令を実行するかどうかを制御できます.これは、コンパイラがプロセッサに条件付きでこれらの命令を無視するように通知することができるため、小さなブロックのコード上でジャンプせず、命令のプリフェッチを無効にしないため、パフォーマンスに有利である.
キャリブレーション
itaniumプロセッサでのキャリブレーションを考慮することが重要です.ポインタは64ビット境界でキャリブレーションする必要があります.そうしないと、キャリブレーション異常が発生します.unalignedキーワードを使用すると、キャリブレーションされていないポインタの違いを許可できますが、パフォーマンスのコストがかかります.通常、#pragma packコマンドを使用して、コンパイラに構造のキャリブレーションを処理させることができます.これにより、コード内の構造を手動で較正するのではなく、32ビットと64ビットの異なる較正(コンパイル時)に使用する構造を指定できます.