配列の処理について教えてください – プログラミング – Home

配列の処理について教えてください
 
通知
すべてクリア

[解決済] 配列の処理について教えてください


rie
 rie
(@rie)
ゲスト
結合: 22年前
投稿: 12
Topic starter  

こんにちは。rieと申します。
配列処理の方法について教えて頂きたいのですが、宣言文以外で
配列への値の代入を行とき、for文を回して代入していく以外の方法は無いのでしょう
か?
データ数が大きくなると処理に時間がかかってしまうので...
また、2次元配列A[*][N] と B[*][M]の値の交換に関しても、for文を使わずに出来る方法
があったら教えてください。
初歩的な質問で申し訳ありませんが、よろしくお願いします。


引用未解決
トピックタグ
ku
 ku
(@ku)
ゲスト
結合: 25年前
投稿: 312
 

漠然としているので答えにくいですが
int A[10][20];
でしたら、全ての要素を0とか-1なら
memset(A, 0, sizeof(A));// 0
memset(A, 0xff, sizeof(A));// -1
なんてのはできます
char A[10][20];のようにcharの配列なら0~0xffまでなら
memset()で初期値を与えることができます
ただし、memsetは全てに対して同じ値しか設定できません
どんな値のパターンを代入したいのですか?

A[*][N]とB[*][M]の交換ってのはどんな感じですか?
同じ型と仮定したら
tmp = A[*][N];
A[*][N] = B[*][M];
B[*][M] = tmp;
が交換だと思うけど?
僕にはforでやる方法というのが分かりませんけど


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

kuさんが既に答えておられるので同じ数値で初期化する件は良いとして
ある特定のパターンだったとするとループを使わないで行う方法は無いと
思います。forを使おうが、whileを使おうがたいして変わりません。
ループでまわして処理する場合、データ数が多くなれば処理時間がかかるのは
当たり前です。
ただ、最近のハードウエアは性能が良いので体感的にも遅いというのは
いったいどれくらいの規模のデータを設定しようとしているんでしょう。
はたまた、よほどスペックが低いハードを使っているのか。
かかる時間があまりにも長いというのであれば、プログラム構造から考え直す
べきでしょう。

A[*][N]とB[*][M]の交換についてもAのどの要素をBのどの要素に入れたいのかで
処理がまったく変わります。
二次元配列がどういったものなのかきちんと把握しないでこの議論をしても
あまり意味が無いと思います。
また、あなたがやりたいことが正確に記述されていないのも問題をややこしくしていま
す。
質問する場合は、公開できる情報は出来るだけ公開してください。
これはあなた自身の頭の中を再整理するという面でも意味があると思います。


返信引用
rie
 rie
(@rie)
ゲスト
結合: 22年前
投稿: 12
Topic starter  

memsetというやり方は知りませんでした。ありがとうございます。

値の交換の方については説明不足ですみませんでした。
倍精度の要素を持つ1000×1000位の行列の演算をしているのですが、
その中でN列とM列の値の交換が頻繁に出てくるので高速にやりたいと思っています。
今までは
for(int i = 0; i < 1000; i++){
TEMP= DATA[i][N];
DATA[i][N] = DATA[i][M];
DATA[i][M] = TEMP;
}
という風にやっていたのですが、こういった操作をポインタを使って高速に行う
事は出来ないでしょうか? よろしくお願いします。


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

倍精度で 1000X1000 程度の行列という事ですが、全部で何バイトになるでしょうか?
およそ 4M バイトですね。これは CPU のキャッシュに納まる量ですか?
キャッシュミスによる速度の低下の方が多少の工夫による速度向上を上回るかもしれません

ただ、その行列の転置行列の場合はあなたの例よりもう少し早いかもしれません
(飛び飛びにアクセスしないで、連続してアクセスするから、キャッシュミスの発生が少ない)
//// DT[1000][1000] は DATA[1000][1000] の転置行列
for (int i =0; i <1000; ++i) {
TEMP =DT[M][i];
DT[M][i] =DT[N][i];
DT[N][i] =TEMP;
}

>こういった操作をポインタを使って高速に行う事は出来ないでしょうか?
ポインターで記述したから早くなるわけでは有りません。それに最近のコンパイラーの最適化は
馬鹿に出来ません。却って、下手にポインターを使うより使わない方が最適化できるかも
しれません。そういったことは予測は困難で、実際に計測するのが一番確実でしょうし、
コンパイラーが生成したオブジェクトコードを見てみるのもいいでしょう

インテルでは Pentium 等に最適化したコードがはけるというコンパイラーを発売していますし
数学演算用のライブラリーも発売しています。そういうものを試すのもいいでしょう
(体験版が試用出来ます -- コンパイラーは英語版だったと思いますが VisualStudio 6/2002
でも使えるようです(詳しくは Intel のサイトで調べて下さい))


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

最近のコンパイラは結構賢くなっていてプログラマが小手先で対抗しようとしても
無駄に終わる場合が多いようです。
むしろ素直なコードを書いてコンパイラの最適化に任せた方が良い結果が出る事も
あります。

rieさんのスキルが今ひとつつかめません。
memsetを知らないのにポインタを使って高速化できないかとかいわれてますし。
ある程度のプログラムを組んだことがあれば、memsetのようなメモリ操作系の
関数は当然使っていると思いますし。

100万個のデータでは時間がかかっても当然だと思います。
いくら単純なデータの転送といってもかかる時間は0ではありませんから。

あと、プロセッサパックを入れると最適化に不具合が出るという話をどこかで
聞いたんですが、大丈夫でしょうか。


返信引用
汎
 汎
(@汎)
ゲスト
結合: 22年前
投稿: 43
 

ほんとに処理時間を気にする必要があるなら、
インラインアセンブラでMMXやSSE,SSE2命令を使った初期化関数
コピー関数をつくりましょう。


返信引用
rie
 rie
(@rie)
ゲスト
結合: 22年前
投稿: 12
Topic starter  

お返事ありがとうございます。
その後、memcpy関数を使ってみたら値の交換は多少速くなりました。

Intelのコンパイラについては知りませんでした。
興味があるので今度試してみようと思います。

> rieさんのスキルが今ひとつつかめません。
> memsetを知らないのにポインタを使って高速化できないかとかいわれてますし。
> ある程度のプログラムを組んだことがあれば、memsetのようなメモリ操作系の
> 関数は当然使っていると思いますし。
プログラム歴は1年位です。memset関数は今回初めて知りました。

色々と勉強になりました。皆さんありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました