プロが教える店舗&オフィスのセキュリティ対策術

ケース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)は並列処理を行わない場合は、上から順番に実行していくだけなので問題はありません。)

A 回答 (5件)

通常、並列処理(マルチプロセスやマルチスレッド)は、特殊な状態になるため、設計段階から、共有データ、排他制御、同期処理、などに注意しないと、思った通りの結果が得られなかったり、排他制御で、同時にイベント待ち状態になりデッドロックを起こしたりします



そのため、マルチスレッドプログラムや、別途プロセスを起動するようなプログラム、また、イベントのコールバックが非同期で呼び出される関数などを実装する場合には、非同期処理を意識してコードを書くべきですし、上記のようなコードを、コンパイルオプションなどによる設計者の指定なしに、コンパイラが勝手に並列処理を行うようなコードを吐くことはないと思ってます

もし、設計者の指定なしに、並列処理を行うコンパイラがあった場合には、その並列処理用のコンパイラの仕様に従って、記述すべきケースだと思いますし、その時の、変数 i はどのような扱いになるのかは、コンパイラ次第だと思いますし、その場合には、ケース1)のコードは並列処理は行われず、ケース2)の場合のみ並列処理になるような可能性もあります


使ったことはないですが、OpenMPの場合、スコープを指定して並列処理を行うようなので、質問者さんのコードで、for文のスコープを並列処理を行うように指定すると、変数 i は、反復変数なので、ケース1)、2)問わず、並列処理ごとで独立した変数として自動で扱われるようです
https://www.openmp.org/wp-content/uploads/openmp …

ただし、それがスタックエリア上の変数になるのか、または、CPUのレジスターを使用するコードを吐き出すのかまでは、分かりません
    • good
    • 0

よく知りませんが、普通に考えれば、ですけど、ダーティなデータがあることを検出した時点で並列実行不可と判定すると思いますけどね。

ただ、ループ回数が10とかなら分岐ミスペナルティの割合が大きくなる可能性があるので、アンローリングして(つまりiはアドレス参照ではなく即値に変換)、ブロックごとに並列可として別個に処理させてしまうかもしれません。もちろん、「...」にデータの依存性がなければの話ですが。
    • good
    • 0

なんの保証もありません。



ケース2でも i が同じアドレスになる場合の方が多いでしょうね。

この辺はコンパイラの裁量次第です。

自動並列化するようにコンパイラなら必要に応じて別アドレスに
変数を割り当てるかもしれないけど・・・
    • good
    • 0

普通にCプログラムを書けば、ロジックを解析して並列化してくれるようなCコンパイラの話でしょうか?


そういう機能はCの言語仕様の外の話なので、そのコンパイラがどういうコードを並列か可能と判断するかというのはそのコンパイラのドキュメントを見る必要があります。読むのが難しければ、コンパイルすると並列化したかどうかの情報を出力してくれるようなオプションがあれば、その結果を見ながらいろいろ修正して、どう書けば並列化してくれるか試してみるか。

直感的には、プログラムで変数の実体が1つだけと宣言されているのに、3つの実体を作り出してくれるかというと、無いかなという気がします。
あるいは、「絶対並列化できるものだけ並列化する」「バグるかも知れないけど積極的に並列化する」とかのオプションがあるかも。


同じように自動的に並列化してくれるFortranコンパイラの話を昔読んだことがありますが、「こう書くと並列化してくれず、こう書く必要がある」とかなりテクニックが必要だった気がします。
    • good
    • 0

どうやって並列処理にするか、次第です。



ケース2でも、そのままでは並列処理にはなりません。
なんらかのライブラリ関数とかマクロとか命令とかを使って、並列処理用に書き換える必要があります。
その際に、変数が全スレッド共通なのか、各スレッド毎に独立なのか、設定できる場合があります。

例えば、OpenMPならprivateという設定があります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!