2019/10/23

OpenMPを使用した並列化

背景


OpenMPを利用して並列化を行い、処理を高速化する必要が出てきたため、OpenMPで並列化処理を記述する方法について記述する

記事の目的


OpenMPで並列化処理を行う際のテンプレートを作成する

OpenMP


ここでは、OpenMPを利用したCプログラムの記述方法について記載する。

OpenMPとは

OpenMP
OpenMPは、OpenMP ARBが提供する並列コンピューティング環境において共有メモリのマルチスレッド処理をサポートするために開発されたAPIである。

利点

  • マルチスレッド並列なプログラムをディレクティブを挿入するだけで実現できる
  • gccなどで標準サポートされており、導入が容易である

テンプレート

OpenMPを利用して並列処理を行うテンプレートを記載する。


// CMakeLists.txt に追記
# For OpenMP
find_package(OpenMP REQUIRED)
if(OpenMP_FOUND)
    message(STATUS "Use OpenMP")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()

// openmp_sample_code.cpp
#include <iostream>
#ifdef _OPENMP
// ヘッダーファイルをインクルード
#include <omp.h>
#endif
int main()
{
#ifdef _OPENMP
    // スレッド数を設定(今回は4スレッド)
    omp_set_num_threads(4);
#endif
#ifdef _OPENMP
    // スレッド数取得
    std::cout << "The number of processors is "<< omp_get_num_procs() << std::endl;
#endif
#ifdef _OPENMP
    // ここから並列処理を行う
    // 【注】カッコ内の処理は、スレッド数回実行される
    #pragma omp parallel
#endif
    {
        int a = 0, b= 0;
#ifdef _OPENMP
        // section毎に並列処理を行う
        #pragma omp sections
#endif
        {
#ifdef _OPENMP
            #pragma omp section
#endif
            {
                // 並列化される処理 1
                a ++; 
            }
#ifdef _OPENMP
            #pragma omp section
#endif 
            {
                // 並列化される処理 2
                b ++; 
            }
        }
#ifdef _OPENMP
        // ここまでの並列処理が完了するまで待機
        #pragma omp barrier
        // シングルスレッド処理
        // 【注】マルチスレッド処理内におけるプライベート変数は引き継がれない場合がある
        //  このコードでは、aまたはbのどちらかが0になる
        #pragma omp single
#endif
        {
            std::cout << "a=" << a << std::endl;
            std::cout << "b=" << b << std::endl;
        }
    }
    size_t i;
    int c = 0;
    int sum = 0;
#ifdef _OPENMP
    // forループを並列化
    // 【注】 #pragma omp parallel内で#pragma omp parallel forすると、2重に並列化するため注意
    //     上記の場合、#pragma omp parallel forを#pragma omp forとする
    // iを各スレッドのプライベート変数に指定
    // 並列化した際にスレッドをを静的(static)に割り当て、チャンクサイズを2に指定
    //        (この場合、i=0,1,4,5,...とi=2,3,6,7,...でスレッドが作られる)
    //        (動的に割り当てる場合はdynamicとする。ただし、スレッド生成コストが増大する)
    // sumは、i*iの処理が並列で行われた後、+=の処理がまとめて行われる
    // orderedは、forループ内にorderedセクションがあることを示す
    #pragma omp parallel for private(i) schedule(static, 2) reduction(+, sum) ordered
#endif 
    for(i = 0; i < 10; ++i)
    {
       sum += i*i;
#ifdef _OPENMP
        // criticalセクション内は、最大で1つのスレッドしか実行されない
        // ただし、スレッド待ちの処理コストが発生する
        #pragma omp critical
#endif
        {
            c += i*i;
            std::cout << "c=" << c << std::endl;
        }
#ifdef _OPENMP
        // orderedセクション内は、順番に実行される
        #pragma omp ordered
#endif
        {
            std::cout << "i=" << i << std::endl;
        }
        std::cout << "sum=" << sum << std::endl;
    }
}

まとめ


  • OpenMPでプログラミングをする際のテンプレートを調査、記載した

参考文献



変更履歴


  1. 2019/10/23: 新規作成
  2. 2019/12/15: コード修正

2019/10/19

特許作成方法のフレームワーク

背景


仕事の中で特許作成を行っているが、アイディア構想から明細書作成までの進め方が定まっておらず、無駄に時間がかかっていた。特許作成の工数削減を削減するため、フレームワークを構築する。

記事の目的


特許作成のフレームワークを策定する

特許作成のフレームワーク


ここでは、特許作成のフレームワークに関する説明について記載する。下記の5ステップで特許創出を行う。

1. 特許に必要な要素の確認

まず、特許創出を開始するにあたり、留意点に関して確認する。特許を創出する際、以下の2つのポイントを意識する。
  • 新規性
  • 新規性は、内容が以下の3項目を満たすことを指す
    • 出願の時点で、守秘義務がない人に知られていない発明であること
    • 出願の時点で、工場見学や報道発表などの公開された場所で実施されていない発明であること
    • 出願の時点で、学会誌、論文、特許などの刊行物や、インターネット上で公開されていない発明であること
  • 進歩性
  • 進歩性は、内容が以下の6項目を満たすことを指す
    • 既存技術に対する最適材料の選択や設計変更に関する発明でないこと
    • 既存技術を組み合わせた発明でないこと
    • 課題に対して既存技術の適用を行った発明でないこと
    • 解く課題が既存の発明と共通している発明でないこと
    • 既存技術と共通の作用や機能を有した発明でないこと
    • 引用文献内に内容の一部が含まれている発明でないこと

2. アイディアの創出

ここでは、アイディアの創出方法について記載する。特許のアイディアを考える際、下記の項目に関して箇条書きで記載する。下記項目に漏れがあると、実用的でないものになる可能性がある。
  1. 背景
  2. 発明を行う分野、領域での実情やトレンドに関して記述する。
    (例) 紙に字を書く道具として、鉛筆が普及している。
  3. 課題
  4. 発明により解きたい課題について記述する。課題が簡潔に記述できるものであるほど、実用性が高い可能性がある。
    (例) 現在の鉛筆は円柱型であり、傾いた机の上に置くと転がって机から落ちやすい問題がある。
  5. 目的
  6. 発明の目的(作用や機能)について記述する。目的も簡潔に記述できるものほど、実用性が高い可能性がある。
    (例) 鉛筆を転がらないようにする。
  7. 方法
  8. 目的を実現するための手法について、具体的に記述する。
    (例) 鉛筆を角型にする。

後のステップで90%以上が没になるため、思いつく限り多くアイディアを創出する。

3.先行特許の調査

ここでは、先行特許の調査方法について記載する。ここで、思いついたアイディアが既出ではないことを確認する。
  1. 先行特許の検索
  2. J-PlatPat等を使用し、関連キーワードなどで先行特許の検索を行う。 この時、検索結果の特許数が100-200件になるように調整する。これは、絞り込み過ぎると関連特許を見落とす可能性があり、逆に多すぎると確認工数が掛かり過ぎるためである。
  3. 1次スクリーニング
  4. 検索結果の特許全てに対して、請求項と図面のみを確認して関連特許であるかを確認する。この時、判定できないものは関連特許とみなす。
  5. 2次スクリーニング
  6. 1次スクリーニング結果、関連特許とみなしたものに対して、実施例を確認し関連特許であるかを確認する。
  7. 新規性・進歩性の確認
  8. 関連特許とアイディアを比較し、「課題」、「目的」、「方法」の3項目で新規性、進歩性があるか確認する。この時、アイディアが関連特許の問題点を解決するものであれば、「課題」にこの特許を記述する。

4.請求項の作成

ここでは、請求項の作成方法について記載する。
  1. アイディアの分解
  2. IT関連の特許の場合、処理のフローチャートやシステムの構成図を作成し、アイディアを要素毎に分解する。
  3. 進歩性の明確化
  4. アイディアの各要素に対して、関連特許との比較を行い、進歩性のある要素を絞り込む。進歩性のある要素が少ないほど、普遍性が増すため特許としての価値が向上する。
  5. 要素の並べ替え
  6. アイディアの要素を必要性順に並べ替える。特許化する際は、要素数を減らしたほうが普遍性が増すため、特許の価値が向上する。
  7. 請求項の作成
  8. アイディアの要素のうち必須な要素(進歩性がある要素と必要性が高い要素)を1項に記載し、2項目以降に必要性順に要素を記述する。

5.実施例の作成

ここでは、実施例の作成方法について記載する。実施例には、実際に実装する場合の処理などを記載する。
  1. 図表の作成
  2. 発明を実施に関する図や絵、写真を作成する。図を用いることで発明の内容が理解しやすくなる。また、UI関連の特許の場合、図は必須である。
  3. アイディアの具体化
  4. アルゴリズムやIO、データ形式などを詳細に記載する。
  5. バリエーションの作成
  6. 実施例は、考えられるパターンをより多く記述する。特にUI関連の特許の場合は、表示方式のバリエーションを網羅するように図を作成する。

まとめ


  • 特許作成の一連の流れについて記載した

参考文献



変更履歴


  1. 2019/10/19: 新規作成

MQTTの導入

背景 IoTデバイスの接続環境構築のため、MQTT(mosquitto)の導入を行った。 記事の目的 MQTT(mosquitto)をUbuntuに導入する mosquitto ここではmosquittoについて記載する。 MQTT MQTT(Message Qu...