ページ 11

共有メモリー上のmemcpy

Posted: 2012年11月06日(火) 13:55
by DOON
DOONといいます。はじめまして。
すごい基本的な事かも知れませんが、よろしくです。
環境 VisualC++ 6.0 sp6 WindowsXP 32Bit ServicePack3
構造体メンバのアライメント 8バイト

プログラムAとBが起動時に,
CreateFile( name, GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,TRUNCATE_EXISTING
, FILE_ATTRIBUTE_NORMAL,NULL);
CreateFileMapping(HANDLE , NULL , PAGE_READWRITE , 0 , 100 , NAME);を使用して、
構造体1をWindowsの共有メモリ―に載せます。
構造体1のメンバは、char buf[100]だけとします。

プログラムAが共有メモリ―を書き込み処理のみ
プログラムBが共有メモリ―の読み込み処理のみを行うようなプログラムにしています。
排他は一切使用していません。

この環境で、プログラムAが共有メモリーの値を 0000000199 から 0000000200に書き換えたとします。
その書き換え方法はmemcpy(共有メモリポインター , "0000000200" , 10)を使用します。

ちょうど、この隙間ぐらいにプログラムBが共有メモリ―を読み込みに行った場合、
0000000299と読み込んでしまう可能性はあるのでしょうか?

memcpyは厳密的に言えば、1バイトずつコピーする もしくは8バイト(32bit)単位で
コピーするとしたら、この状況が起こり得るのでは、ないかと心配しています。

実際、タイマーを使用して、負荷テストプログラムを作成したのですが
現象はでませんでした。

理論的に排他をする必要があるかどうかを知りたいです。
読み込む側が排他を取得するのも、変な気がしています。

intとかだと問題なくて、charだとまずいとかもあるのでしょうか?

よろしくお願いします。

Re: 共有メモリー上のmemcpy

Posted: 2012年11月06日(火) 14:45
by softya(ソフト屋)
CPU内のキャッシュが動作しますので偶然キャッシュ境界を跨がない限り無いかも知れませんが、そんなの当てにするのは間違っています。
あるものとして設計するのが正しいあり方だと思いますが。

Re: 共有メモリー上のmemcpy

Posted: 2012年11月06日(火) 15:41
by DOON
早速の回答ありがとうございます。

>あるものとして設計するのが正しいあり方だと思いますが
おっしゃる通りですね。

少し背景がありまして、10年ぐらい前のプログラムのリプレースになります。
そのころは、1コアのCPUで納品されていました。
今回 Corei5になります。
10年間、問題なく稼働していたみたいです。
今回見直したところ、、このようなソースを発見し、
マルチコアでは、可能性があがるのでは??と思い、質問に至りました。

今回知りたいのは、カラクリになります。
たとえば構造体1のメンバがbuf[7]だとしたら、修正の必要がないのか等を知りたいと思っています。
(アライメントの分は、1命令に保証されているとか、32bitまでの範囲なら、保証されているとか)
(memcpyのからくりは、こうだよ!とか、VisualCの共有メモリーなら、こうだよ?とか)

なるだけ手をかけずに納品するのが、リプレースの仕事のメインだと考えております。(予算的な面です。すいません)
カラクリがわかれば、構造体のメンバをみて、修正すべき、構造体、修正しないでよい構造体のふるいもかけれると思っています。

また、書く側と読む側が、完全に、わかれていれば、排他は必要ないと思ってもいます。

もし、スレ違いならおっしゃってください。

Re: 共有メモリー上のmemcpy

Posted: 2012年11月06日(火) 16:21
by softya(ソフト屋)
読むバッファと書くバッファが完全に分離していて書き込みが終わったことをウィンドウ・メッセージで伝える等の事実上の排他が行われていれば大丈夫です。
ただ、それ以外だとCorei5とPentium時代のCPUではキャッシュ制御の方式がぜんぜん違うと思うので、他コアとメモリが32?バイト単位(一時キャシュの最低単位)などで同期される可能性を否定しきれません。この同期はハードウェア(CPUのアーキテクチャ)レベルだけで行われるはずなのでCPU設計の専門家でも無い限り保証しかねると思います。
※ つまり、ソフトウェアの作りかたやOSの都合ではなくハードウェアがやるので完全には把握しきれないと思われるのです。

【補足】
1コアの場合は、IO同期などのタイミングでプロセスが切り替わるのでmemcpyの最中に他のプロセスが共有メモリを参照する可能性は皆無だったのではないでしょうか?

Re: 共有メモリー上のmemcpy

Posted: 2012年11月07日(水) 09:44
by DOON
重ね重ねの回答ありがとうございます。

確信を得ることができました。

疑わしきは、取り除きます。

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