今日のお題は、プロでもあまり知ってなくても良い話です。
「プロで知らなくていいなら、誰が知ってりゃいいんだよ!」
えーと。。。
超高性能なアプリケーションを、C 言語 (か C++ 言語。要はメモリの管理も書く人に任されている言語) で書きたい人・設計しなきゃなんない人は、知ってた方がいいかな・・・。
なぜ、そういうマニアな話題を取り上げてみたかというと、私が自分の覚え書きのために書いている Web サイトがあるのですが、・・・・ ちなみにこちらです ・・・・
プログラミング徹底解説
それのアクセス統計を見てたら、意外なページがトップでした。
アクセス最多の意外なページとは・・・
ヒープに関する話題
http://keicode.com/windows/win11.php
ずいぶんまぁ、マニアなページを見てくださる方もいるものなんですね (笑)
せっかくなので、この 「ヒープに関する話題」 で何を説明しているか、簡単に説明できるかどうか、やってみたいと思います。
どっちにしても、本当に Windows で高性能なプログラムを書きたい人以外は知らなくていいことなので、大抵の人は読んでもあなたの人生の約には立ちませんよ!!ごめんなさい!!!
では、本日のお題は 「ヒープに関する話題」 の解説です。
C/C++ をやってる人には当然おなじみですが、プログラムからメモリを使わないといけないときは、最初にメモリを割り当てるわけですよね。CRL (C Runtime Library) を使うなら、malloc や calloc を使いますね。 Windows 上で書く人はさらに、Win32 API も使えるので HeapAlloc なども使えたりします。
一言で言うと、メモリの割り当ては、まぁ回数が少ないに越したことは無いんですが、ヒープから割り当てておけばいいのです。
ヒープから割り当てないとなると、どこから割り当てるかというと、仮想メモリの領域割り当てを Windows にお願いして割り当ててもらって、そこを使う、ということなのですが、そんな馬鹿なことはやめましょう。具体的に言うと VirtualAlloc ですが、そこに自分でメモリマネージャを実装するなら別ですが、ちいさいメモリブロックの割り当てを毎回 VirtualAlloc する人なんていません。これは無しです。
高性能なプログラムを書きたい人は、ここからもう一歩進んでヒープ自体を複数作ることを考えていきましょう。
なぜかというと、ヒープへの同時アクセスは禁止されるので、同時アクセスがきても待たされるのです。つまり、10個のスレッドで同じヒープからメモリブロックをとろうとしても、それは順序良く一個一個処理されます。これを処理がシリアライズされるなんていいます。
ヒープはプロセス一個につき、最初から一個用意されているのですが、それをプロセスヒープといいます。で、自前で作ったのは、複数作れるのですが、それ全部ひっくるめてプライベートヒープなんていいます。プロセスヒープばかりに頼りきっていると、メモリ割り当てが集中して、処理に遅延が発生する可能性がある。だから、プライベートヒープを作って、待ちを減らしましょう、ということです。
プライベートヒープを作るのは、何もパフォーマンスの観点だけじゃなく、断片化(フラグメンテーション)対策っていう動機もあるのですが、それはまた後でいつか書こうと思います。
ということで、今日は、すっごく高性能なプログラムを書きたいなら、ヒープも複数用意したほうが良いよ、というお話でした。