mrubyでmemsetやmemcpyが少ない理由.

たぶんmrubyのソースコードを読むときに疑問に思うFAQ的話題な気がしたので,纏めました.
34

疑問: なんで memcpy を使わないで構造体コピーのループ回しているの?

Miura Hideki @miura1729

mrubyのarray.cのarray_copyって素直にmemcpyを使った方が良くない?移植性の理由だろうか?

2013-02-26 22:04:38
Miura Hideki @miura1729

こういう話はissueを書くべきだが、英語は閾が高い。

2013-02-26 22:06:14
眼力 玉壱號 @objectxplosive

.@miura1729 http://t.co/k37XCptcow ですか…うーん、inline 付いている所を見ると size が定数の時に良い code が出るであろうという期待なのかなぁ?(memcpy も inlining される事は多いけど)

2013-02-26 22:09:56
Miura Hideki @miura1729

@objectxplosive gccだと組み込みですし、インライン化されない関数でもちょっとコピー量が増えるとすぐ元が取れると思うのですが。

2013-02-26 22:13:32
眼力 玉壱號 @objectxplosive

.@miura1729 http://t.co/vnkXz1dJ2r を見ると、memcpy から自前に変更したみたいです…

2013-02-26 22:15:12
眼力 玉壱號 @objectxplosive

.@miura1729 committer の @monamour555 氏に問うてみる他ないのではと…

2013-02-26 22:41:00

というわけで,パッチ投げた人が登場

もなか @monamour555

@miura1729 @objectxplosive はい.array_copy のアレは,単純に移植性の理由です.ISO C標準につきあうと,こういうコードを書かざるを得ません.普通は memset でしょ,という部分で構造体の代入をしているのも同じ理由です.

2013-02-26 23:05:27
もなか @monamour555

@miura1729 @objectxplosive あと,いくつかのアホな処理系(gccとかgccとかgccとか)がmemcpy() でメモリアライメント関係でトラブる例があるってのもあります.その辺の話は,この辺りに…. https://t.co/i3ZLbrypZi

2013-02-26 23:10:36

リンク先には,次のような記述があります.


Looks like on ARM architecture, GCC and other compilers may mis-optimize memcpy and assume certain memory alignment, whichcreates errors on unaligned access. To avoid this, either don't use memcpy, or, cast the pointers to char* to disable this misoptimization. More details here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html

意訳) ARM みたいに memcpy で最適化に失敗するコンパイラがあるんだよ.


Also MIPS, for example http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755
On x86, they will work as its architecture is alignment tolerant.

意訳) MIPSもね.x86で問題がないのは,アライメントを気にしなくても大丈夫なアーキテクチャだからさ.


もなか @monamour555

@miura1729 @objectxplosive 単純なコピーループですので,真っ当な最適化を行う処理系なら memcpy の inline 展開と同等のコードを吐くであろうとの読みはあります.いざとなれば,ユーザ責任で memcpy に書き換えることもできますし

2013-02-26 23:18:55

疑問: array_copy を inline 宣言すると太らないの?

mattn @mattn_jp

mruby の array_copy、なんで memcpy じゃないんだろ。被ってないし sizeof 使えるから memcpy でも良い気がするんだけど。inline だからベクトル化はされそうだけど要所で inline されて太らないだろうか

2013-02-26 22:30:12
もなか @monamour555

@mattn_jp gcc だと,target triplet に依りますが,memcpy と memset は割と勝手に inline 展開されます.一方,inline 宣言も,実際に展開するかはコンパイラが決めます(これがC99 inline の嫌らしいところ).

2013-02-26 23:23:56

そんなわけで,どちらにしても太るかどうかはコンパイラの胸先三寸で決まります.特定のコンパイラを想定できない mruby では,対処の手がありません.

mattn @mattn_jp

@monamour555 と言うことはmemcpyでもいいと言うことですか?それともベクトル化を期待する修正ですか?

2013-02-26 23:32:34
もなか @monamour555

@mattn_jp https://t.co/mOzIqZD7gb ここにも書いたのですが,ISO C 標準から外れたコードを書いて処理系のバグにぶつかっても泣かないなら,memcpy でもよいと思いますよ.

2013-02-26 23:35:37

もしかして: freestanding環境に無いから?

参考: ISO C言語仕様では,下層にOSが存在する環境(hosted環境)と,OSの存在が期待できない環境(freestanding環境)が定義されています.
機器組込みも応用の一つとして考えているmrubyでは,freestanding環境のことを考慮することは大切なのです.

鯉江 @koie

よくわからんけどstandaloneでもうごくようにmrubyはlibcをつかわないってのもあるのかな?memcpyってstdcだよね?

2013-02-27 01:19:34
とみながたけひろ @takehiro_t

@koie ホスティッド環境だけでなく、フリースタンディング環境でも使えるようにしたい、ということかと思います

2013-02-27 01:22:42
鯉江 @koie

@takehiro_t それです(hosted/freestanding)。http://t.co/JKQvU9O68lで環境をなんていったかなぁと検索してわからなかった。。。

2013-02-27 01:27:24
もなか @monamour555

@koie 仰る通り,mem{cpy|set}() については,freestanding環境ではサポートが無いという話もあります. ただ,自作のmemcpy()でもmis-alignのリスクはあります. 危なくなさそうな memcpy() は,mruby に残してあります.

2013-02-27 09:24:46