![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
ケース1)
int main() {
int i;
for(i=0; i<10; i++) {
...
}
for(i=0; i<10; i++) {
...
}
for(i=0; i<10; i++) {
...
}
...
return 0;
}
ケース2)
int main() {
for(int i=0; i<10; i++) {
...
}
for(int i=0; i<10; i++) {
...
}
for(int i=0; i<10; i++) {
...
}
...
return 0;
}
上記のケース2)の場合、変数iは各for文ごとに定義しているので、並列処理を行った場合でもコンパイラがそれぞれ別のアドレスを振ってくれると思うのですが、
ケース1)の場合、並列処理を行った場合でもコンパイラは、変数iに対して、別のアドレスを振ってくれることになるのでしょうか?(ケース1)は並列処理を行わない場合は、上から順番に実行していくだけなので問題はありません。)
No.3ベストアンサー
- 回答日時:
通常、並列処理(マルチプロセスやマルチスレッド)は、特殊な状態になるため、設計段階から、共有データ、排他制御、同期処理、などに注意しないと、思った通りの結果が得られなかったり、排他制御で、同時にイベント待ち状態になりデッドロックを起こしたりします
そのため、マルチスレッドプログラムや、別途プロセスを起動するようなプログラム、また、イベントのコールバックが非同期で呼び出される関数などを実装する場合には、非同期処理を意識してコードを書くべきですし、上記のようなコードを、コンパイルオプションなどによる設計者の指定なしに、コンパイラが勝手に並列処理を行うようなコードを吐くことはないと思ってます
もし、設計者の指定なしに、並列処理を行うコンパイラがあった場合には、その並列処理用のコンパイラの仕様に従って、記述すべきケースだと思いますし、その時の、変数 i はどのような扱いになるのかは、コンパイラ次第だと思いますし、その場合には、ケース1)のコードは並列処理は行われず、ケース2)の場合のみ並列処理になるような可能性もあります
使ったことはないですが、OpenMPの場合、スコープを指定して並列処理を行うようなので、質問者さんのコードで、for文のスコープを並列処理を行うように指定すると、変数 i は、反復変数なので、ケース1)、2)問わず、並列処理ごとで独立した変数として自動で扱われるようです
https://www.openmp.org/wp-content/uploads/openmp …
ただし、それがスタックエリア上の変数になるのか、または、CPUのレジスターを使用するコードを吐き出すのかまでは、分かりません
No.5
- 回答日時:
よく知りませんが、普通に考えれば、ですけど、ダーティなデータがあることを検出した時点で並列実行不可と判定すると思いますけどね。
ただ、ループ回数が10とかなら分岐ミスペナルティの割合が大きくなる可能性があるので、アンローリングして(つまりiはアドレス参照ではなく即値に変換)、ブロックごとに並列可として別個に処理させてしまうかもしれません。もちろん、「...」にデータの依存性がなければの話ですが。No.4
- 回答日時:
なんの保証もありません。
ケース2でも i が同じアドレスになる場合の方が多いでしょうね。
この辺はコンパイラの裁量次第です。
自動並列化するようにコンパイラなら必要に応じて別アドレスに
変数を割り当てるかもしれないけど・・・
No.2
- 回答日時:
普通にCプログラムを書けば、ロジックを解析して並列化してくれるようなCコンパイラの話でしょうか?
そういう機能はCの言語仕様の外の話なので、そのコンパイラがどういうコードを並列か可能と判断するかというのはそのコンパイラのドキュメントを見る必要があります。読むのが難しければ、コンパイルすると並列化したかどうかの情報を出力してくれるようなオプションがあれば、その結果を見ながらいろいろ修正して、どう書けば並列化してくれるか試してみるか。
直感的には、プログラムで変数の実体が1つだけと宣言されているのに、3つの実体を作り出してくれるかというと、無いかなという気がします。
あるいは、「絶対並列化できるものだけ並列化する」「バグるかも知れないけど積極的に並列化する」とかのオプションがあるかも。
同じように自動的に並列化してくれるFortranコンパイラの話を昔読んだことがありますが、「こう書くと並列化してくれず、こう書く必要がある」とかなりテクニックが必要だった気がします。
No.1
- 回答日時:
どうやって並列処理にするか、次第です。
ケース2でも、そのままでは並列処理にはなりません。
なんらかのライブラリ関数とかマクロとか命令とかを使って、並列処理用に書き換える必要があります。
その際に、変数が全スレッド共通なのか、各スレッド毎に独立なのか、設定できる場合があります。
例えば、OpenMPならprivateという設定があります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2重定義って??
-
DWORDの実際の型は何でしょうか
-
関数の実体定義にヘッダファイ...
-
C++の規格
-
int main の前のint add(int a,...
-
visualstudio C# テキストボッ...
-
C++のfor文について
-
構造体の要素すべてに対する四...
-
STL vectorの初期化
-
C言語で乱数がうまく効きません...
-
値を返り値に返すのと参照渡し...
-
C++でboolにintの値を代入する...
-
enumについて
-
64bit → 32bit型へのキャスト
-
void func( void )について
-
unsigned *という宣言について
-
エラー「invalid conversion fr...
-
VC6でlong longでエラー?
-
ハンドルされていない例外が発...
-
クラスを配列で確保する場合の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
visualstudio C# テキストボッ...
-
C++のfor文について
-
2重定義って??
-
long型の定数の末尾にLを付ける...
-
typedef enumの使い方を教えて...
-
main.c:7:43: warning: implici...
-
C++でboolにintの値を代入する...
-
構造体の要素すべてに対する四...
-
intとINTの違いは?
-
ハンドルされていない例外が発...
-
DDVによるメッセージの変更
-
変数の型を定義しなかった場合...
-
【#define】 defineで定義した...
-
C++ クラスをメンバにもつクラ...
-
構造体の宣言でエラーが出ます。
-
プログラムの中で別のmainを呼...
-
void func( void )について
-
エラー「invalid conversion fr...
-
関数の実体定義にヘッダファイ...
おすすめ情報