第 8 章 特定のチップ セットの拡張サポート
10.2 ユーザーモード ドライバのパフォーマンスの向上
一般的にメモリマップの領域への転送は、I/O マップの領域への転送よりも高速です。これは、WinDriver では関数を呼び出さずに、ユーザーモードからメモリマップの領域に直接アクセスできるためです (10.2.1 を参照)。
また、WinDriver API ではブロック (文字列) 転送を使用したり、いくつかのデータ転送関数の呼び出しを 1 つのマルチ転送関数の呼び出しにまとめて (10.2.2 を参照)、I/O およびメモリ データ転送のパフォーマンス を向上できます。
10.2.1 メモリ マップの領域への直接アクセス
WDC_xxxDeviceOpen() 関数 (PCI / PCMCIA / ISA) または低レベル WD_CardRegister() 関数で
PCI / PCMCIA / ISA を登録すると、ユーザーモードおよびカーネルモードにおけるカードの物理メモリ領域
へのマップが返されます。これらのアドレスを使用して、どちらのモードからでもカード上のメモリ領域へ直接 アクセスできます。これにより、ユーザーモードとカーネルモード間のコンテキストスイッチとメモリへアクセス するための関数呼び出しオーバーヘッドが削除されます。
WDC_MEM_DIRECT_ADDR マクロは、カード上の指定されたメモリアドレス領域に直接アクセスするための ベースアドレス (ユーザーモードから呼び出された場合はユーザーモードマップ、Kernel PlugIn ドライバ [第 11 章 ] から呼び出された場合はカーネルモードマップ) を返します。マップされたベースアドレスを指定 されたメモリ領域内のオフセットと共に WDC_ReadMem8/16/32/64 マクロや
WDC_WriteMem8/16/32/64 マクロへ渡し、ユーザーモードまたはカーネルモードから、カード上のメモ リアドレスに直接アクセスすることができます。
さらに、WDC_ReadAddrBlock() と WDC_WriteAddrBlock() を除く WDC_ReadAddrXXX() 関数お よび WDC_WriteAddrXXX() 関数はすべて、呼び出しコンテキスト (ユーザーモードまたはカーネルモー ド) のマップを使用して、直接メモリ アドレスにアクセスします。
低レベル WD_xxx() APIを使用すると、WD_CardRegister() により、カードリソースアイテムの構造体
である pCardReg->Card.Item[i] の dwTransAddr フィールドおよび dwUserDirectAddr フィー ルドに保存されている、カードの物理メモリ領域のユーザーモードマップおよびカーネルモードマップが返 されます。dwTransAddr は、WD_Transfer() や WD_MultiTransfer() の呼び出しにおいて、また
は Kernel PlugIn ドライバ [第 11 章 ] から直接メモリにアクセスする際に、ベースアドレスとして使用します。
ユーザーモードから直接メモリにアクセスするには、dwUserDirectAddr を通常のポインタとして使用し ます。
どの方法でカード上のメモリにアクセスする場合でも、特に文字列転送コマンドを使用する際には、データ 型のサイズに応じてベースアドレスのアラインが重要です。または、転送を小さく分割します。データをアラ インする最も簡単な方法は、バッファを定義する際に、基本の型を使用することです。
例:
BYTE buf[len]; /* BYTE 転送の場合 – アラインなし */
WORD buf[len]; /* WORD 転送の場合 – 2 バイト境界でアライン */
UINT32 buf[len]; /*DWORD 転送の場合 – 4 バイト境界でアライン */
UINT64 buf[len]; /* QWORD 転送の場合 – 8 バイト境界でアライン */
10.2.2 ブロック転送および複数の転送のグループ化
メモリアドレスや (メモリアドレスとは異なり、直接アクセスすることができない) I/O アドレスから、またはメモリ アドレスや I/O アドレスへ大量のデータを転送するには、次の方法を使用して関数呼び出しオーバーヘッド およびユーザーモードとカーネルモード間のコンテキストスイッチを削減し、パフォーマンスを向上させま す。
z WDC_ReadAddrBlock() / WDC_WriteAddrBlock() または低レベル WD_Transfer() 関 数を使用してブロック (文字列) 転送を行う。
z WDC_MultiTransfer() または低レベル WD_MultiTransfer() 関数を使用して複数の転 送を 1 つの関数呼び出しにまとめる。
10.2.3 64 ビット データ転送を行う
注意: 実際の 64 ビット転送の実行能力は、ハードウェア、CPU、ブリッジなどによる転送のサポートに依存 し、これらの仕様の組合せになどのよっても影響を受けます。
WinDriver は、サポートしている 64 ビット Windows および Linux プラットフォーム (一覧はセクション 9.6 を 参照) および 32 ビット Windows および Linux x86 プラットフォーム上での、64 ビット PCI データ転送をサ ポートしています。PCI ハードウェア (カードおよびバス) が 64 ビットの場合、対象のホストオペレーティング システムが 32 ビットでも、より高い処理能力をハードウェアに与えることができます。
この新しい技術は、32 ビットプラットフォームで以前では実現できなかったデータ転送の能力を飛躍的に高 めます。WDK または他のドライバ開発ツールで記述したドライバよりも高いパフォーマンスを WinDrinver で 開発したドライバが発揮します。Jungo 社によるベンチマークテストでは、64 ビットデータ転送で 32 ビット データ転送に比べ、データ転送速度が飛躍的に向上する結果が得られました。WinDriver で開発されたド ライバは、通常の 32 ビットデータ転送で得られる性能よりも高い数字を得られることが実証されました。
次の方法で 64 ビット データ転送を実行できます。
z WDC_ReadAddr64()または WDC_WriteAddr64() を呼び出す。
z アクセス モード WDC_SIZE_64 と共に WDC_ReadAddrBlock()または WDC_WriteAddrBlock() を呼び出す。
z QWORD 読み取り/書き込み転送コマンドと共に WDC_MultiTransfer()、低レベル
WD_Transfer()、または WD_MultiTransfer() を呼び出す (詳細は、各関数の説明を参 照してください)。
WDC_PciReadCfg64() / WDC_PciWriteCfg64() または WDC_PciReadCfgBySlot64() / WDC_PciWriteCfgBySlot64() を使用して、PCI 設定空間からまたは PCI 設定空間への 64 ビット転送 を実行することもできます。
第 11 章
Kernel PlugIn について
この章では、WinDriver の Kernel PlugIn の機能について説明します。
注意: Windows CE にはカーネルモードとユーザーモードの区別がないため Kernel PlugIn を実行できま
せんが、Kernel PlugIn を使用しなくても最高のパフォーマンスを達成できます。
Windows CE で割り込み処理率を向上するには、セクション 9.2.8 を参照してください。