自己満足日記。
飽きっぽいので期待しないでください。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
作成していた習作のプラグインに分散処理にあたって、
当初利用していたOpenMPは必ず再頒布パッケージが必要になり、
こんな大したことないものを利用するために
一々ライブラリが必要だと言うのはとてもやりづらいので
動的にしかビルドできないOpenMPから
静的にビルド可能な内蔵の関数へと切り替える必要があり、
これらの間の構文の違いを吸収するためOpenMPで利用していたコードから、
これらの間で流用可能なコードに書き換えてみた。
OpenMPでのループの並列化は基本的にはこう。
この場合、仮に4threadで処理するのなら
1thread目:0~249番のループ
2thread目:250~499番のループ
3thread目:500~749番のループ
4thread目:750~999番のループ
てな感じで分散して処理される。処理の順番はバラバラ。
schedule句によってこの分配は変えられる。
実は特にループの為の構文を使わず、
若干の書き換えで一般のparallel構文でほぼ同様に分散することもできる。
総カウント数をthread数で割って0~249までは1thread目が~、
などと事前に計算する必要はない。
#pragma omp parallel
for(int x = omp_get_thread_num(); x<1000; x += omp_get_num_threads()){
//特に構えることなく並列化できるコード
}
omp_get_thread_num()
引数を取らず、並行領域内で自分が何thread目かを返す関数。
omp_get_num_threads()
引数を取らず、その並行領域の総thread数を返す関数。
この場合、上と同様に4threadで処理するのなら
1thread目:0,4, 8,12,16,20,24,...番のループ
2thread目:1,5, 9,13,17,21,25,...番のループ
3thread目:2,6,10,14,18,22,26,...番のループ
4thread目:3,7,11,15,19,23,27,...番のループ
という形で分散される。schedule(dynamic, 1)とほぼ同じ形になる。
そしてAviutlのvoid multi_thread_func関数においてほぼ同様の挙動になるように書き換えるとこうなる。
for(int x = thread_id; x < 1000; x += thread_num){
//特に構えることなく並列化できるコード
}
わぁ簡単(ぱちぱち
thread_idとthread_numの説明は良いでしょう。
当初利用していたOpenMPは必ず再頒布パッケージが必要になり、
こんな大したことないものを利用するために
一々ライブラリが必要だと言うのはとてもやりづらいので
動的にしかビルドできないOpenMPから
静的にビルド可能な内蔵の関数へと切り替える必要があり、
これらの間の構文の違いを吸収するためOpenMPで利用していたコードから、
これらの間で流用可能なコードに書き換えてみた。
OpenMPでのループの並列化は基本的にはこう。
#pragma omp parallel for for(int x = 0; x<1000; x++){ //特に構えることなく並列化できるコード }
この場合、仮に4threadで処理するのなら
1thread目:0~249番のループ
2thread目:250~499番のループ
3thread目:500~749番のループ
4thread目:750~999番のループ
てな感じで分散して処理される。処理の順番はバラバラ。
schedule句によってこの分配は変えられる。
実は特にループの為の構文を使わず、
若干の書き換えで一般のparallel構文でほぼ同様に分散することもできる。
総カウント数をthread数で割って0~249までは1thread目が~、
などと事前に計算する必要はない。
#pragma omp parallel
for(int x = omp_get_thread_num(); x<1000; x += omp_get_num_threads()){
//特に構えることなく並列化できるコード
}
omp_get_thread_num()
引数を取らず、並行領域内で自分が何thread目かを返す関数。
omp_get_num_threads()
引数を取らず、その並行領域の総thread数を返す関数。
この場合、上と同様に4threadで処理するのなら
1thread目:0,4, 8,12,16,20,24,...番のループ
2thread目:1,5, 9,13,17,21,25,...番のループ
3thread目:2,6,10,14,18,22,26,...番のループ
4thread目:3,7,11,15,19,23,27,...番のループ
という形で分散される。schedule(dynamic, 1)とほぼ同じ形になる。
そしてAviutlのvoid multi_thread_func関数においてほぼ同様の挙動になるように書き換えるとこうなる。
for(int x = thread_id; x < 1000; x += thread_num){
//特に構えることなく並列化できるコード
}
わぁ簡単(ぱちぱち
thread_idとthread_numの説明は良いでしょう。
PR
少なくともnVidia環境の場合、propertiesがNULLだとCL_INVALID_PLATFORMが返ってくるので、propertiesを指定する。
タイトル変えよう。
※プラグイン作成の解説記事ではないです。
独学でCとかC++とかやってみてたんだし
何かそれっぽいものを作ってみようということで、
Aviutlで拡大縮小をするプラグインを作ってみることにした。
用いるアルゴリズムは平均画素法(面積平均法・積分法とも)。
大まかな解説は以下のURLを参照の事。
まるも製作所 Diary 12月20日(水) 縮小アルゴリズム(3)- 平均画素法
陶見の窓 画像リサイズ「面積平均法」
開発に使うのはVisual C++ 2008 Express Edition。別に2010でも良い。
あとはAviutlのお部屋からAviUtl Plugin SDKを落とす。
ビルド時についてはまるも製作所 Diary 1月6日(木) VC.NET での拡張 AVI 出力ビルド方法を参照。
マニュアル代わりに永遠に工事中 AviUtlプラグインの作り方。
マイルール
○モチベーション維持のため他で見られない点をどこかに混ぜる
・間引きはしない:普通はほとんど差が出ないのでやります
○適当に間隔開けてから読んでも分かるようにする
・マジックナンバーは可能な限り避ける:あとから見ると何の数字だかワカラン
・とりあえず動くように書く:これ重要
・最適化(笑)は後回しにする:カッコつけちゃいけませんぜ
・変数名・関数名等は長くて良い:略しすぎると後で読んだときイミフ
○細かいところはコンパイラに投げる
・constは可能な限り使う:何かあるとコンパイラが教えてくれる
・変数は初期化する:うっかり未初期化のまま使うと嫌なので
・警告レベルは最大にする:コンパイラは友達だよ
・C++で書く:Better C 的な
どうしても処理が遅い時の解決法
・除算を避ける:クソ遅いと評判
・同じ計算を何度もしない:同じ出力なら定数を宣言しておきましょう
・分散処理する:OpenMPとかOpenCLとか使ってみたいじゃなーい
今回用いる平均画素法は10pxからの6pxにリサイズしたいのなら、一度3倍して最小公倍数である30pxに拡大し、その後5px毎に区切りそこの総和を3で割っていく感じです。
そして最初にまともに動いたのがこんな感じのもの。
当時のコードは残ってないので記憶で書いてますが無駄なところは再現出来てるかと。
独学でCとかC++とかやってみてたんだし
何かそれっぽいものを作ってみようということで、
Aviutlで拡大縮小をするプラグインを作ってみることにした。
用いるアルゴリズムは平均画素法(面積平均法・積分法とも)。
大まかな解説は以下のURLを参照の事。
まるも製作所 Diary 12月20日(水) 縮小アルゴリズム(3)- 平均画素法
陶見の窓 画像リサイズ「面積平均法」
開発に使うのはVisual C++ 2008 Express Edition。別に2010でも良い。
あとはAviutlのお部屋からAviUtl Plugin SDKを落とす。
ビルド時についてはまるも製作所 Diary 1月6日(木) VC.NET での拡張 AVI 出力ビルド方法を参照。
マニュアル代わりに永遠に工事中 AviUtlプラグインの作り方。
マイルール
○モチベーション維持のため他で見られない点をどこかに混ぜる
・間引きはしない:普通はほとんど差が出ないのでやります
○適当に間隔開けてから読んでも分かるようにする
・マジックナンバーは可能な限り避ける:あとから見ると何の数字だかワカラン
・とりあえず動くように書く:これ重要
・最適化(笑)は後回しにする:カッコつけちゃいけませんぜ
・変数名・関数名等は長くて良い:略しすぎると後で読んだときイミフ
○細かいところはコンパイラに投げる
・constは可能な限り使う:何かあるとコンパイラが教えてくれる
・変数は初期化する:うっかり未初期化のまま使うと嫌なので
・警告レベルは最大にする:コンパイラは友達だよ
・C++で書く:Better C 的な
どうしても処理が遅い時の解決法
・除算を避ける:クソ遅いと評判
・同じ計算を何度もしない:同じ出力なら定数を宣言しておきましょう
・分散処理する:OpenMPとかOpenCLとか使ってみたいじゃなーい
今回用いる平均画素法は10pxからの6pxにリサイズしたいのなら、一度3倍して最小公倍数である30pxに拡大し、その後5px毎に区切りそこの総和を3で割っていく感じです。
そして最初にまともに動いたのがこんな感じのもの。
当時のコードは残ってないので記憶で書いてますが無駄なところは再現出来てるかと。