質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1175閲覧

C言語のmemcpy関数について

aiueo12345

総合スコア41

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/06/19 11:02

memcpyはどのように行われる関数なのでしょうか?

私は動的配列(int型)のプログラムを書き、100000000個のデータを挿入、削除させました。

すると、初期配列サイズが①1の場合と②100000001の場合とで実行時間の差異がほとんど見られませんでした。
(その差はおよそ0.22秒)

挿入時に一杯であれば、元の配列の内容を新たに作った大きさ2倍の配列にmemcpyで移し換え、元の配列は解放します。

②の場合には配列は拡張することがなく、①の場合には27回拡張することになりますが、ここの差はほとんどないと思います。

問題はmemcpy関数で移し変える時だと思いもす。

最大で67108864(2^26)個のデータを移し変えることになりますが、memcpyはそれでも差が出ないような仕様なのですか?

また、ライブラリ関数の中身を見る方法があれば、合わせて教えてください。

諸事情によりプログラムは載せられませんが、ご回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

実行時間の差異がほとんど見られませんでした。

(その差はおよそ0.22秒)

コンピューターの世界からすれば、0.22秒違う、という話です。3GHzのクロックであれば、0.22秒間に6.6億クロックが過ぎていきます。

投稿2019/06/19 12:27

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2019/06/20 02:54

ご回答ありがとうございます。 昨日ちょうど大学でクロックについて学んだところでした。 このように変換すると大きな差だと意識できますね。
guest

0

メモリアクセスにかかる時間ですが、
(1個から2^26個までの和で)2^27個=512MBもあるとキャッシュには乗らずメインメモリまでアクセスされるでしょうから、メモリの転送速度を調べてみると、
最近主流のDDR4-2400で19.2GB/秒。クアッドチャンネルなら4倍。
76.8GB/sで0.5GB×2(読み+書き)を転送する時間は0.013秒と計算できます。シングルチャンネルでも0.052秒。
実際には理論値が出るわけではないにせよ、0.22秒には遠いです。

投稿2019/06/19 13:11

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2019/06/20 02:56

ご回答ありがとうございます。 理論値を計算すると、データ数が莫大であるために大きな遅延が起こっていることが確認できるのですね。 このような計算は知らなかったため、大変勉強になりました。
ikadzuchi

2019/06/20 04:55

違います。データ数が莫大であることでは遅延が説明できないことを示しています。 27回拡張していることが遅延の主要因だと思います。
aiueo12345

2019/06/20 09:54

なるほど、転送時間は小さく、これだけでは0.22秒かからないので、それ以外で時間がかかっている。 それは拡張だと考えられるわけですね。拡張で遅延が起きるというのは意外でした。
guest

0

アセンブラ一発です。・・・その前にECX,ESI,EDIレジスタの設定が有りますが。
ストリング命令(ブロック転送命令)
REP MOVS m32, m32

投稿2019/06/19 11:28

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2019/06/19 11:35

ご回答ありがとうございます。 標準ライブラリ関数の中身は高級言語では書かれていないのですね。 memcpyはO(1)で行えるということですか?
episteme

2019/06/19 11:39

> 標準ライブラリ関数の中身は高級言語では書かれていないのですね。 か否かはライブラリ作者の勝手。 > memcpyはO(1)で行えるということですか? ちがいます。
aiueo12345

2019/06/19 11:46

epistemeさん 標準ライブラリ関数については色々な場合があるのですね。 cateyeさんのリンクによると、memcpyの一つのコピーが一発で実行できるみたいなので、やはりmemcpyは文字数分ループということでしょうか。
cateye

2019/06/19 11:58 編集

REP MOVS m32, m32 の実行クロックをググってみましたが見つかりませんでした。(キャッシュに乗ると転送データのアクセスだけになると思いますが・・・)メモリの読み書きにも時間はかかります。ただ、1億ぐらいでは我々が感じられる時間差は出ないと思います。 >一つのコピー REPプリフィックスを付ければECXレジスタの値だけ繰り返せます。
aiueo12345

2019/06/19 12:02

1億というと大きなデータ数だと感じましたが、コンピュータにとってはそこまでのデータ量ではないのですね。(もちろん、扱うデータ型にもよるとは思いますが。) 色々勉強になりました。ありがとうございました。
guest

0

ベストアンサー

「memcpy ソース」でぐぐってみましょう

投稿2019/06/19 11:13

y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2019/06/19 11:21

ご回答ありがとうございます。 ググってみたところ、個人が書いたようなものしか見つかりませんでしたが、それらによると配列を一つずつたどっていました。 これだと、今回のプログラムにおいて大きな差につながりそうだと感じますが、実際はそうではないのですね。 配列をたどって1億個のデータをコピーしてもそれほど時間計算量には影響がないことがわかりました。 また機会があればよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問