fc2ブログ

Win32並行処理プログラミング入門19

 この記事は、Win32並行処理プログラミング入門18の続きです。今回は、並行アルゴリズムの考え方について解説します。
 並列処理で考えねばならないのは、リソースを長時間ロックもしくは排他制御していないかという点です。ですから、サンプルのこの部分は問題があります。

//サンプルより抜粋
//並列的に実行するメソッド
void AddFunc( int count )
{
    EnterCriticalSection( &number_section ); //開始地点
    long tmp = this->getNumber();
    for ( int i = 0; i < count; i++ ) {
        ++tmp;
    }
    this->setNumber( tmp );
    LeaveCriticalSection( &number_section ); //終了地点
}

このやり方では、1つのスレッドしかAdd関数の処理を実行できない問題があります。排他制御の時間が長すぎます。
 その観点から、次の様なプログラムを思いつくと思います。

//排他制御の時間を少なくする
void AddFunc( int count )
{
    for ( int i = 0; i < count; i++ ) {
        EnterCriticalSection( &number_section ); //開始地点
        this->setNumber( this->getNumber() + 1 );
        LeaveCriticalSection( &number_section ); //終了地点
    }
}

このプログラムは、排他制御の時間が短く、他のスレッドが共有リソースを操作するチャンスを積極的に与えています。しかし、このプログラムもオーバーヘッドが高いという問題があります。
 クリティカルセクションの開始と終了は、それなりのコストが必要となります。そのコストを頻繁に払うとオーバーヘッドが高くなり、逆にパフォーマンスが下がる可能性が十分にあります。
 また、実際はサンプルとは違い、実装の詳細が分からない場合が多々あります。その様な状況下では、この様な実装に関する知識が要求される方法を採れないでしょう。何故ならば、実装が隠蔽されている場合、どのリソースを使っているか分からないからです。そうなると、メソッドもしくは関数そのものをクリティカルセクションで囲まないとならないかもしれません。ですが、それでは並行度が下がりますし、リソースを把握していない場合、他のメソッドも同じリソースを操作する可能性を考えると、非常に危険だと言えます。
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

アジャイル開発と業務分析10

 この記事は、アジャイル開発と業務分析9の続きです。引き続き、アジャイル開発で業務分析を行う際に注意するべき点について書きます。
 前回述べたように、アジャイル開発はお客様の業務に合わないと失敗します。すなわち、アジャイル開発のプロセスそのものを改善しつつ開発作業を進めます。理想的、アジャイル開発へのフィードバックがお客様の業務の一部となる事です。そうなれば、システム開発は成功したのも同然となります。
 これは非常に大切な事です。我々が納品するシステムは、いずれお客様の仕事環境の一部となります。開発中のシステムに触れる事により、移行コストおよび教育コストを下げる事が出来ます。また、開発したシステムに愛着を持って頂けます。お客様に愛してもらえないシステムは導入失敗だと言えます。開発者がどれほど自信を持っていても、最終的に評価するのはお客様なのです。
 お客様との信頼関係は非常に大事です。システムをバージョンアップする際も、お客様との信頼関係が悪いままだと、負の遺産を引き継ぐ事になってしまいます。
 ウォターフォール開発モデルでは、お客様との壁がありましたが、これでは良いシステムは開発出来ません。我々日本人は、お客様に奉仕する精神で改善を積み重ね技術大国と言われておりました。今はそれを胸を張って言えない状態です。アジャイル開発は、我々日本人に向いた開発形態だと私は思います。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

Win32並行処理プログラミング入門18

 この記事は、Win32並行処理プログラミング入門17の続きです。前回は並行処理で起こりがちな問題を述べました。今回はその解決法を書きます。
 クリティカルセクションで逆にパフォーマンスが下がるのは、直列アルゴリズムで考えているからです。サンプルのFooクラスは、逐次的な処理を想定してプログラミングされています。ですから、直列アルゴリズムだと言えます。この直列アルゴリズムを並行処理で無理やり使うと、概念のギャップがボトルネックとなって表れます。
 継承の問題については、合成もしくは並行アルゴリズムで実装しなおす事により解決できます。そもそも並行処理をしたい場合は、並行処理用のアルゴリズムを考えなくてはなりません。理想的には並列処理用に実装しなおすのが一番です。しかし、複雑なクラスを再利用する場合、再実装するのは困難です。その場合は合成を行い、並行処理用のクラスを実装するのがベストです。
 次回以降これらの解決方法を、サンプルを提示しつつ解説していきます。

テーマ : プログラミング
ジャンル : コンピュータ

C#でビルド後自動的にNUnitを実行する方法

 みんなテストファーストやっているよね?やっていない人は絶対やるべし!
テストファーストを実践したい人は、ビルド後自動的にテストが実行されるようにしたいと思う。今回その方法を書きます。
 NUnitをインストールする方法は簡単だから省略します。インストールして、テストプロジェクトを作ったら、「ソリューションエクスプローラー」内のテストプロジェクト名を右クリックしてから、プロパティをクリックします。その後、テストプロジェクトのプロパティを設定する画面が表示されるから、そこで「ビルドイベント」タブをクリックして下さい。後は、ビルド後に実行するコマンドラインに設定するだけです。

"C:\NUnit 2.5.9\bin\net-2.0\nunit-console" $(TargetFileName)
※パスは自分がインストールした場所です

ポイントは""でパスを囲む事です。テストプロジェクトを作る方法は今回紹介しません。 これでサクサク開発作業が出来ます。
もちろん、VBも同じ要領で出来ると思います。

テーマ : プログラミング
ジャンル : コンピュータ

実践的オブジェクト指向分析入門13

 この記事は、実践的オブジェクト指向分析入門12の続きです。前回は、要求分析について書きました。今回は分析モデルについて書きます。
 問題を分析する方法は、分析モデルを作成する事です。OMTでは、静的構造を表すオブジェクトモデル、相互作用の順序を表す動的モデル、データ変換を表す機能モデルの3つの分析モデルが存在します。これらの分析モデルは対等の関係ではありません。プロジェクトの性質により、重視するべき分析モデルが変わります。例えば、コンパイラなどのシステムソフトウェアは機能モデルを重視し、タイミングが重要な業務システムならば動的モデルを重視するべきです。
 分析モデルは、問題が解決されるまで詳細化していきます。ただし、実装を定義してはなりません。あくまでも現実世界のモデル化である事を忘れてはなりません。行き過ぎた分析は害になります。何時分析を止めるのかは永遠のテーマですが、私は経験から導き出された一つの指標を持っています。
 分析を止める条件は、システム設計が出来るようになるまでです。しかし、ここで注意せねばならない事があります。それは、部分的に設計できる場合はどうするかです。
 部分的にシステムが設計できる状況下では、際限なく分析を進めがちです。ですが、分析をやり過ぎると害になりますので、分析が終わった問題領域については分析を止めるべきです。これを実現するために、問題領域を適切な単位で分けます。これが出来るのは、オブジェクト指向分析特有の利点です。
 もし、問題領域を切り分けられないのであれば、問題の分析が足りない、もしくはオブジェクト指向に関する知識がないのが原因です。適切に現実をオブジェクト化できれば、自然と切り分ける事が可能となります。もちろんすぐに出来る事ではありません。問題領域の抽象度を徐々に下げて、分析を繰り返し行う事により、適切に問題領域をオブジェクト化できます。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

Win32並行処理プログラミング入門17

 この記事は、Win32並行処理プログラミング入門16の続きです。今回は、Win32並行処理プログラミング入門14で触れていたサンプルの問題点から、クリティカルセクションの使用方法について解説します。
 Win32並行処理プログラミング入門14で提示したサンプルには問題があります。処理結果は正しいものの、処理効率は悪いと言えます。何故ならば、クリティカルセクションを使用した場合、単一スレッドしか共有リソースにアクセス出来ず、他のスレッドはEnterCriticalSection関数を実行した後に待たされるので、並行処理化する事によりパフォーマンスを下げる結果になってしまっています。
 また、継承によって並行処理専用のクラスを作成する場合、元のクラス(サンプルの場合Foo)の子クラスをどう扱うのかが問題となります。元のコードをコントロールできるとは限りませんので、継承で対処するのは困難だと言わざるをえません。何故ならば、既存のオブジェクトを使用する元のコードに影響を与える可能性がありますし、コードの保守性が悪くなります。ですから、この件を継承で対処するのは問題があると言えます。
 次回以降、この2つの問題の解決法を説明していきます。

テーマ : プログラミング
ジャンル : コンピュータ

中の人の徒然草389

おはようございます。朝にブログをUPしたインドリです♪
この日記の分類は「裏事情」なので、たまにはそれらしい事を書きます。
私は並行処理/並列処理の記事を結構書いています。その時感じたのですが、やはり並行処理/並列処理は説明が難しいです。
難しい理由は色々あるのですが、第一にサンプルを用意するのが難しいです。
今まで並行処理/並列処理にとってHello worldレベルのサンプルを提示してきましたが、サンプル長いですよね?
一番簡単な方法は数学とグラフィック関係のサンプルを提示する事なのですが、それはあくまでもパフォーマンスにしかなりません。何故ならば、効果を示す事は出来ても並行処理/並列処理そのものの説明にはなっていないからです。
読む側の気持ちに立つと、どこからが数学/グラフィックで、どこからが並行処理/並列処理のサンプルなのか分かりません。数学/グラフィックを知らない人は、両方勉強しなくてはなりません。これは避けるべき事です。
これは、異業種の人に対してシステムの説明をしているので分かるのですが、一度にいくつも説明をしてはなりません。聞き手が混乱するだけです。本当に伝えたいのであれば、本題を目立つ様にせねばなりません。説明には強弱が必要なのです。
この事は、異業種の方にシステムの説明をする場合を考えてみると、分かりやすいと思います。無目的に全てを理解して頂こうとすれば、情報処理技術の全てを説明する事になってしまいます。しかし、そんな事を異業種の人は望んでいません。彼らの立場で考えれば、「そんなこと知りたくはない。オタクがコンピュータについて熱く語っているな。」としか思われない事が分かると思います。
ですから、並行処理/並列処理以外の余計な事は極力簡略化し、本題である並行処理/並列処理の特徴が目立つサンプルを用意せねばなりません。しかし、並行処理/並列処理は元々難しい技術なので、簡略化する事は困難です。説明するべき対象をかなり深く知らねばなりません。
ちなみに私は、並行処理を学ぶために、簡単なOSの実装、簡単なコンパイラの作成、並行処理/並列処理のライブラリを実装、アセンブラプログラミングなどをしています。
それに、確か5・6年ぐらい前までは、今よりも資料・ライブラリなどが少なく、パイプラインを自分で実装したりせねばならない時代でした。
ここ最近は、自分でライブラリを書かねばならないほどではないので、ずいぶん楽になりました。その一方で、隠蔽されている部分が多くなって設計が難しくなった部分もありますが・・・
閑話休題。
他に説明が難しい理由は、従来の常識を覆さなくてはならないので、間違いを提示して説明しなくてはならない事です。
並行処理/並列処理は、直列的な逐次処理とは根幹が異なります。
また、並列処理の進化が、如何にして間違えないかを追求する方向へ向かっているのもポイントです。
そこで、直列アルゴリズムしか考えた事がない人達に向けて、間違えやすいポイントを説明するために、間違いを提示する事になります。
やった事がない人は分からないと思いますが、間違いを提示するのは意外と難しい事です。
効果的に間違えるのには、正しい事を解説するよりも深い知識が必要となります。
それに加え、頭が固い人の猛攻を受ける羽目になります。
その辺は、オブジェクト指向プログラミングを知らないのにも関わらず毛嫌いする人に対し、オブジェクト指向プログラミングを教えるのと同じです。
いや、並行処理/並列処理はそれディープな技術なので、もしかしたら、それ以上に難しいでしょう。
それを知らない人が、頑固に否定してくるのを説得するのは、非常に骨が折れます。
何故ならば、知らないのにも関わらず、知らない事を否定する人に対して、正しい事を言っても受け入れようとしないからです。
コミュニケーションは、双方が聞く意思を持っていないと成立しません。ですが、知らないけども否定したい人は、そもそも聞く気すらないのです。
さらに、インターネットでは、文章でやり取りをする事になりますが、文章の読解能力がない人は、意思疎通そのものが難しくなります。
インターネット上で、話しがかみ合わない経験をした人は多いと思いますので、この辺は分かって頂けると思います。
ですが、並行処理/並列処理はこれからの時代必須の知識/技術です。
並行処理/並列処理を伝えるためにこれからも頑張ります。

テーマ : 裏事情
ジャンル :

Win32並行処理プログラミング入門16

 この記事は、Win32並行処理プログラミング入門15の続きです。今回も引き続き、クリティカルセクションについて解説します。
 CRITICAL_SECTION構造体の変数は、使用する前に必ずInitializeCriticalSection関数で初期化します。InitializeCriticalSection関数を実行すると、CRITICAL_SECTION構造体のメンバが更新され、クリティカルセクション機能を使用する準備が整います。
 ここからが本番です、クリティカルセクションでは共有リソースを操作するコードブロック(クリティカルリージョン)をEnterCriticalSection関数とLeaveCriticalSection関数で囲みます。

//サンプルより抜粋

//並列的に実行するメソッド
void AddFunc( int count )
{
    EnterCriticalSection( &number_section ); //開始地点
    long tmp = this->getNumber();
    for ( int i = 0; i < count; i++ ) {
        ++tmp;
    }
    this->setNumber( tmp );
    LeaveCriticalSection( &number_section ); //終了地点
}

コメントで示した様に、EnterCriticalSection関数はクリティカルリージョンの開始地点で、LeaveCriticalSection関数はクリティカルリージョンの終了地点で使用します。
 EnterCriticalSection関数からLeaveCriticalSection関数までの範囲(リージョン)は、共有リソースは1つのスレッドしか操作できなくなります。こうする事により、複数のスレッドによるデータの不整合は避けられます。しかし、別の問題も発生します。その問題については後で説明します。
 最後に、共有リソースにアクセスしないと判明した時点で、DeleteCriticalSection関数を呼び出します。ただし、共有リソースにアクセスしているスレッドがある時、この関数を使用しないでください。その場合の結果は不確定です。
 クリティカルセクションの使用法は一見簡単です。しかしながら、先に述べたように、クリティカルセクションは別の問題と課題を生みだします。続く...

テーマ : プログラミング
ジャンル : コンピュータ

Win32並行処理プログラミング入門15

 この記事は、Win32並行処理プログラミング入門14の続きです。今回は、クリティカルセクションについて解説します。
 紛らわしい事に、Windowsのスレッド同期機能であるクリティカルセクションと、概念であるクリティカルセクションという用語が存在します。ひとまず、概念であるクリティカルセクションについて解説します。
 今まで見てきたように、複数のスレッドで並行処理をする際に問題となるのは、共有リソースを操作した場合です。それを防ぐ方法は、共有リソースを操作している間、単一スレッドしか共有リソースを処理できないようにする事です。この共有リソースを操作している間のコードブロックの事を、クリティカルセクションもしくはクリティカルリージョンと呼びます。
 Windowsでクリティカルリージョンの間、単一のスレッドしか共有リソースをアクセスできないようにする機能を、クリティカルセクションと呼びます。クリティカルセクション機能を使うには、一定のルールの下4つの関数(InitializeCriticalSection、EnterCriticalSection、LeaveCriticalSection、DeleteCriticalSection)と1つの変数(CRITICAL_SECTION構造体)を使用せねばなりません。
 一番最初にするべき事は、共有リソースに対応するCRITICAL_SECTION構造体の変数を用意する事です。共有ソースが複数ある場合は、複数のCRITICAL_SECTION構造体の変数を用意します。CRITICAL_SECTION構造体は、クリティカルセクション機能を制御するために必要なデータと考えて下さい。CRITICAL_SECTION構造体のメンバの扱い方はWindowsだけが知っていればよい事とされており、自分で操作してはなりません。

テーマ : プログラミング
ジャンル : コンピュータ

Mosh学習日記5

 今日は久しぶりに朝Moshをしてみました。余りにも久しぶりだったので、次にどこを読もうか迷ってしまいました。本日は、眠気眼をこすりながら迷っている間に、数十分が経って殆ど収穫がありませんでした。
 それでも楽しく読みました。前にも読んだところですが、Moshはポートを重要視していて、テキストポートの初期化時にスキャナを初期化しています。そして、MoshはBisonで構文解析を行っています。やはり本格的なコンパイラを作ろうと思ったら、Bisonが要るようですね。そういえば、昔yacc/lexを触った事があるけど、随分長い間パーサジェネレーターを触っていないな・・・
 おっと、いかんいかん。睡魔に襲われてしまった。他は今まで読んだところの再確認になってしまいました。う~ん、頭が働かない。朝Moshをする日は、もっと早く起きて目を覚ましてからしなくてはならないですね・・・
 

テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

インドリ

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人がいるので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、言いがかかり等の行為を禁止します。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (9)
C++ (11)
C# (370)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (33)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (4)
WPF (0)
WF (2)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター