7

memmove が C でどのように実装されているかを理解するのを手伝ってくれる人がいますか? 特別な条件が 1 つしかありません。

if((src<dst)&&((src+sz) > dst))

copy from the back

また、スタックの成長方法にも依存しますか?

4

3 に答える 3

32

数学的には、それらが重複しているかどうかについてまったく心配する必要はありません。src未満の場合はdst、最後からコピーするだけです。srcより大きい場合はdst、最初からコピーします。

srcとが等しい場合dstは、すぐに終了します。

これは、ケースが次のいずれかであるためです。

1) <-----s----->                start at end of s
                 <-----d----->

2) <-----s----->                start at end of s
            <-----d----->

3) <-----s----->                no action
   <-----d----->

4)          <-----s----->       start at beginning of s
   <-----d----->

5)               <-----s----->  start at beginning of s
   <-----d----->

重複がなくても問題なく機能し、条件を簡素化します。

後方よりも前方にコピーする効率的な方法がある場合は、重複をチェックして、可能であればより効率的な方法を使用していることを確認する必要があります。つまり、上記のオプション 1 を最初からコピーするように変更します。

于 2010-08-26T06:25:10.827 に答える
6

2 つのメモリ領域がオーバーラップしない場合、memmoveを memcpy に変換できます。明らかに、memcpy はほとんどのシステムで非常に最適化されています (私が使用しているシステムの 1 つは、展開されたループから、最大のスループットをサポートする SSE 操作まで、本のほぼすべてのトリックを利用しています)。

2 つのメモリ領域がオーバーラップする場合、すべての意図と目的のために、コピーされる領域は一時バッファーに移動され、一時バッファーは元のバッファーの上にコピーされます (すべて memcpy を使用する可能性が最も高い)。最初から作業することも、オーバーラップ領域を使用して後ろから作業することもできません。これは、処理中に少なくとも一部のデータが常に破損することになるためです。

そうは言っても、libc コードを見てから長い時間が経過しているため、まだ考えていない memmove とオーバーラップ領域の最適化があるかもしれません。

memmove は、スタックが大きくなる方法にはまったく依存しません。メモリの 1 つの領域を別の場所にコピーするだけです。重複する領域を処理し、memcpy は処理しないことを除いて、memcpy とまったく同じです。

編集:実際には、もう少し考えてみてください...移動自体に応じて、正しい「ソース」(いわば)から行けば、後ろから作業することができます(たとえば、ソース<宛先かどうか)。ここでnewlib の実装を読むことができ、tt もかなりよくコメントしています。

于 2010-08-26T05:53:57.367 に答える
2

コンパイラに依存します。優れたコンパイラは、ターゲット プロセッサの命令セットとバス幅に応じて適切な最適化を使用します。

于 2010-08-26T05:52:15.537 に答える