「OpenMP」の版間の差分
ナビゲーションに移動
検索に移動
imported>MikeCAT (作成) |
Administrator (トーク | 投稿記録) |
||
1行目: | 1行目: | ||
− | + | '''OpenMP'''とは、数行の[[おまじない]]を書いて[[コンパイルオプション]]を追加するだけで、 | |
多くの処理対象に対し同じような処理をする処理を早く終わらせることができるようになる[[定数倍高速化]]ツールである。 | 多くの処理対象に対し同じような処理をする処理を早く終わらせることができるようになる[[定数倍高速化]]ツールである。 | ||
2024年4月10日 (水) 02:45時点における最新版
OpenMPとは、数行のおまじないを書いてコンパイルオプションを追加するだけで、 多くの処理対象に対し同じような処理をする処理を早く終わらせることができるようになる定数倍高速化ツールである。
処理に使うコンピュータの性能や使用する対象のソースコードにもよるが、 使用しない場合に比べて大体処理時間を86~22%にできる。 ただし、使用しない場合より実行中のCPU使用率が高くなる。 また、高速化効果が得られず、逆に遅くなってしまう環境もあるので注意が必要である。
使用方法[編集 | ソースを編集]
#include <stdio.h>
#include <stdlib.h>
int get_flag(unsigned char* buf,int index) {
return (buf[index>>3] & (1<<(7-(index&7))));
}
void set_flag(unsigned char* buf,int index,int flag) {
if(flag) {
buf[index>>3]|=1<<(7-(index&7));
} else {
buf[index>>3]&=~(1<<(7-(index&7)));
}
}
int main(int argc,char* argv[]) {
int calc_ryo=20;
unsigned int calc_max;
unsigned int calc2_max;
unsigned char* calc_buffer;
unsigned buffer_max;
unsigned i,j;
if(argc>1)sscanf(argv[1],"%d",&calc_ryo);
if(calc_ryo<0 || calc_ryo>31)calc_ryo=20;
calc_max=1u<<calc_ryo;
calc2_max=1u<<((calc_ryo+1)/2);
buffer_max=calc_max>>3;
calc_buffer=malloc(buffer_max);
if(calc_buffer==NULL)return 1;
printf("max: %u\n",calc_max);
for(i=0;i<buffer_max;i++)calc_buffer[i]=0xFF;
set_flag(calc_buffer,0,0);
set_flag(calc_buffer,1,0);
for(i=2;i<=calc2_max;i++) {
if(get_flag(calc_buffer,i)) {
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(j=i+i;j<calc_max;j+=i) {
set_flag(calc_buffer,j,0);
}
}
}
free(calc_buffer);
return 0;
}
例えばこのコードのように、多くの対象に同じような処理をしているfor文の前に
#pragma omp parallel for
というおまじないを書く。そして、
>gcc -O2 -fopenmp -o prime.exe prime.c -static
のように、コンパイルオプションに-fopenmpを追加する。
このことによりOpenMPが有効化され、実行時間が比較的短くなることが期待される。
注意点[編集 | ソースを編集]
OpenMPは、多くの対象に、互いに関係ない同じような処理をしている場合の高速化に有効である。
処理が互いに関係ある場合、例えば値の合計を取るなどの場合は、特殊な書き方が必要である。