« 特電の商品発送箱が変わります! | トップページ | PCI ExpressのDMA転送を改善する »

2017.08.09

WindowsのDMAとMapRegister

スキャッタギャザーDMAを発行しようとして試行錯誤していたのですが、どうしても1MByte以上の転送を行おうとするとブルースクリーンになってしまいました。

最初はMapTransferという関数を使っていたのですが、オブジェクトの開放の手順がよくわからなかったので、途中からGetScatterGatherListを使うようにしたのですが、1MByteの転送をしようとすると物理アドレス(論理アドレス)のリストを作るだけで、実際の転送をしなくてもブルースクリーンになってしまいます。

100回くらい青い画面を出して、ようやくわかってきました。

sun

スキャッタギャザーDMAでは、ユーザがmallocで確保したバッファが実際に割り当てられている物理メモリのアドレスを調べて、そこをめがけてFPGAからDMA転送するので、原理的にはデータのコピーが発生しません。

Sgtransfer

しかし、この方法には問題があります。

PCI Expressのアドレスはデフォルトでは32bitなので、4GBまでの転送先アドレスしか指定できません。パソコンのCPUのアドレスは4GBでは収まらないメモリ空間を持っています。それゆえ、メモリRD/WRを発行しても、メインメモリの先頭の4GBまでしかアクセスできないことになってしまいます。

そこで、Windowsでは、マップレジスタというものが用意されています。マップレジスタというのは、ハードウェアデバイス用の仮想メモリのようなもので、PCI Expressから指定された転送先アドレスを実際のDIMMの物理アドレスに変換する機能です。

つまり、PCI ExpressからメモリRD/WRで指定してくるアドレスは、パソコンのメモリの物理アドレスではなく、ハードウェア版のアドレス変換機構を通す前のアドレスなのです。これを論理アドレスといいます。

そして、物理アドレスと論理アドレスを変換する機能がマップレジスタなのです。

Mapregister_2

しかし、マップレジスタというのは実際に存在するわけではなく、そういう機能があったらいいな、というものをHALがエミュレートしているのです。

わけがわからないとは思いますが、つまりこういうことです。

  • MapTransferやGetScatterGatherListを実行すると、DMA転送先のアドレスとして、下位4GBを指すようなものが返される。
  • この下位4GBのバッファには、実際にユーザ用のバッファが割り当てられているわけではなく、DMA転送の前後で、カーネルがこっそりメモリコピーを行う

Mapregister2

Windowsはこんな仕組みでDMAを実行しているのです。

sun

ブルースクリーンになってしまう原因はマップレジスタの数でした。私が新しく買ったWindows10 64bitマシンでは、デバイスドライバの中で「このデバイスは0x10000000(256MByte)のDMAを行う」と申告しても、マップレジスタを256個しか割り当ててくれませんでした。

Mapreg_office_32bit

マップレジスタ1個は1つの物理ページ(=4096バイト)のアドレス変換テーブルなので、1MByte分のアドレス変換しかしてくれないのです。これ以上の長さのDMAをしようとしてもマップレジスタが無いので、NULLを返してしまい、それを開放しようとしてブルースクリーンになっていたのですね。

家のPCでやってみたところ512個のマップレジスタが取れました。

Mapreg2

これなら2MBまでのDMA転送ができます。

sun

実際に連続してスキャッタギャザーDMAをやってみたところ、アプリケーションレベルで測って毎秒1GB/secの速度で転送できました。

Dmardwr

しかし、1MBや2MBのサイズのDMA転送しかできないのですから、効率が悪いですね。

Windows7や8で32bit版ドライバを動かしていたときにはもっと確保できていたと思うのですが・・

重要なことは、スキャッタギャザーといってもユーザのバッファにDMA転送しているわけではなく、裏でカーネルがこっそりコピーしているということです。そのカーネルがこっそりコピーできるサイズが、1MBや2MBしかないのです。

|

« 特電の商品発送箱が変わります! | トップページ | PCI ExpressのDMA転送を改善する »

コメント

コメントを書く



(ウェブ上には掲載しません)




« 特電の商品発送箱が変わります! | トップページ | PCI ExpressのDMA転送を改善する »