SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

連載記事

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

CodeZine BOOKS(コードジン・ブックス)は、CodeZineの連載からカットアップした、開発現場の課題解決に役立つ書籍シリーズです。

書籍に関する記事を見る

'); googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', function(e) { var ad_id = e.slot.getSlotElementId(); if (ad_id == 'div-gpt-ad-1659428980688-0') { var ad = $('#'+ad_id).find('iframe'); if ($(ad).width() == 728) { var ww = $(window).width(); ww = ww*0.90; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/728+","+ww/728+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/728+","+ww/728+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/728+","+ww/728+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/728+","+ww/728+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(90*ww/728)+"px;width:"+728+"px;}", 0 ); } else { if ($(window).width() < 340) { var ww = $(window).width(); ww = ww*0.875; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/320+","+ww/320+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/320+","+ww/320+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/320+","+ww/320+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/320+","+ww/320+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(180*ww/320)+"px;width:"+320+"px;}", 0 ); } } } }); }); } else { document.write('
'); document.write('
'); }
特集記事

C++11 : スレッド・ライブラリひとめぐり

Visual Studio 2012 RC であそんでみたよ

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルファイル (36.4 KB)

 C++11が提供するスレッド・ライブラリの使い心地を、Visual Studio 2012 RCでの試運転を兼ねてざっくりと体感してみましょう。

  • X ポスト
  • このエントリーをはてなブックマークに追加

 5月の末、Visual Studio 2012 RCがリリースされました。僕は根っからのC++屋ですから、興味の対象は第一にVisual C++ 2012(以下、VC11)です。現Visual C++ 2010(VC10)にはlambdaなどの国際標準C++11の一部をサポートしていますけど、VC11ではさらにC++のサポート範囲が広がっています。今回はVC++11で新たに追加された標準スレッド・ライブラリのご紹介です。

十万未満の素数はいくつある?

 「1とそれ自身以外の約数を持たない数」が素数です。言い換えれば「2以上n未満のすべての数でnを割り切ることができなければ、nは素数」ですわね。だからnが素数であるか否かを判定する関数はこんなカンジ。

リスト1
// nは素数?
bool is_prime(int n) {
  for ( int i = 2; i < n; ++i ) {
    if ( n % i == 0 ) {
      return false;
    }
  }
  return true;
}

 このis_primeを使って「lo以上hi未満の範囲にある素数の数」を求める関数count_primeは

リスト2
// lo以上hi未満の範囲に素数はいくつある?
int count_prime(int lo, int_hi) {
  int result = 0;
  for ( int i = lo; i < hi; ++i ) {
    if ( is_prime(i) ) {
      ++result;
    }
  }
  return result;
}

 10万未満の素数を勘定してみましょう。

リスト3
/* 
 * M未満の素数はいくつある?
 */
void single(int M) {
  chrono::system_clock::time_point start = chrono::system_clock::now();
  int result = count_prime(2,M);
  chrono::duration<double> sec = chrono::system_clock::now() - start;
  cout << result << ' ' << sec.count() << "[sec]" << endl;
}

int main() {
  const int M = 100000;
  single(M);
}

/* 実行結果:
9592 1.64009[sec]
*/

 10万までの整数には1割弱の素数があるんですねぇ。僕のマシン(i7-2600K、Windows7-64bit)では1.6秒ほどで答えを出してくれました。

0:Windows API

 この計算をマルチスレッドによる高速化を試みます。戦略はいたって単純、素数か否かの判定範囲、[2,M) (2以上M未満,M=100000)をスレッド数で等分します。たとえばスレッドふたつなら [2,M/2) と [M/2,M)に。んでもって各スレッドに分割された範囲での素数の勘定を分担させ、それぞれの結果を全部足し合わせればよかろう、と。

 まずはWindows APIで実装します。範囲[lo,hi)をn等分するクラスdiv_rangeを用意します。

リスト4 div_range.h
#ifndef DIV_RANGE_H_
#define DIV_RANGE_H_

// [lo,hi) を n等分する
template<typename T =int>
class div_range {
private:
  T lo_;
  T hi_;
  T stride_;
  int n_;
public:
  div_range(T lo, T hi, int n) 
    : lo_(lo), hi_(hi), n_(n) { stride_ = (hi-lo)/n; }
  T lo(int n) const { return lo_ + stride_ * n; }
  T hi(int n) const { return (++n < n_) ? lo_ + stride_*n : hi_; }
};
#endif

 分割された範囲ごとにスレッドを起こし、全スレッドが完了したところで積算します。

リスト5
/* Win32 thread のためのwrapper */

// <0>:loi, <1>:hi , <1>:result
typedef tuple<int,int,int> thread_io;

DWORD WINAPI thread_entry(LPVOID argv) {
  thread_io& io = *static_cast<thread_io*>(argv);
  get<2>(io) = count_prime(get<0>(io), get<1>(io));
  return 0;
}

/* 
 * M未満の素数はいくつある?
 */
void multi(int M, int nthr) {
  vector<HANDLE> handle(nthr);
  vector<thread_io> io(nthr);
  div_range<> rng(2,M,nthr);

  for ( int i = 0; i< nthr; ++i ) {
    io[i] = thread_io(rng.lo(i), rng.hi(i), 0);
  }

  chrono::system_clock::time_point start = chrono::system_clock::now();
  for ( int i = 0; i< nthr; ++i ) {
    handle[i] = CreateThread(NULL, 0, &thread_entry, &io[i], 0, NULL);
  }
  WaitForMultipleObjects(nthr, &handle[0], TRUE, INFINITE);
  chrono::duration<double> sec = chrono::system_clock::now() - start;

  int result = 0;
  for ( int i = 0; i < nthr; ++i ) {
    CloseHandle(handle[i]);
    result += get<2>(io[i]);
  }
  cout << result << ' ' << sec.count() << "[sec] : " << nthr << endl;
}

int main() {
  const int M = 100000;
  for ( int i = 1; i < 10; ++i ) multi(M, i);
}

/* 実行結果:
9592 1.6651[sec] : 1
9592 1.21607[sec] : 2
9592 0.970055[sec] : 3
9592 0.752043[sec] : 4
9592 0.631036[sec] : 5
9592 0.52903[sec] : 6
9592 0.549031[sec] : 7
9592 0.497028[sec] : 8
9592 0.470027[sec] : 9
*/

 スレッド数1~9で実行すると、8個の論理コアを持つi7では当然のことながらスレッド8個あたりでスピード頭打ちとなります。3倍ちょっと速くなってますね。Window-APIで実装する場合、スレッドの本体であるcount_primeをスレッドに乗っけるためのwrapper(このサンプルではthread_ioとthread_entry)が必要になります。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
1:thread

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6639 2012/06/29 14:00
" ); }

おすすめ

アクセスランキング

  1. 1
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説 NEW
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表 NEW
  4. 4
    健全なソフトウェア設計の第一歩! 既存のPHPソースコードからクラス図を自動生成しよう
  5. 5
    開発チームに必要なのは生産性だけじゃない! 健全性も計測し、良い開発者体験を生むために
  1. 6
    VSCodeをUML図やフローチャート作成に使ってみよう
  2. 7
    売上か? 面白い技術か? エンジニア組織が直面するジレンマに、エンジニア経営者 漆原氏が切り込む
  3. 8
    計測と改善をひたすら繰り返したら、年間コストを1億円削減した──不確実性の高いプロジェクトに挑む NEW
  4. 9
    約9割の企業がIT人材不足を実感、「プロリア プログラミング」による調査によって明らかに NEW
  5. 10
    「正解のない仕事」に備える効率的な学び方とは? エンジニアリングマネージャーが認知科学と共に紐解く NEW

アクセスランキング

  1. 1
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説 NEW
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表 NEW
  4. 4
    健全なソフトウェア設計の第一歩! 既存のPHPソースコードからクラス図を自動生成しよう
  5. 5
    開発チームに必要なのは生産性だけじゃない! 健全性も計測し、良い開発者体験を生むために
  6. 6
    VSCodeをUML図やフローチャート作成に使ってみよう
  7. 7
    売上か? 面白い技術か? エンジニア組織が直面するジレンマに、エンジニア経営者 漆原氏が切り込む
  8. 8
    計測と改善をひたすら繰り返したら、年間コストを1億円削減した──不確実性の高いプロジェクトに挑む NEW
  9. 9
    約9割の企業がIT人材不足を実感、「プロリア プログラミング」による調査によって明らかに NEW
  10. 10
    「正解のない仕事」に備える効率的な学び方とは? エンジニアリングマネージャーが認知科学と共に紐解く NEW
  1. 1
    VSCodeをドキュメント作成に活用――テキストエディタ、Markdownエディタの設定と拡張機能を解説
  2. 2
    ITエンジニア本大賞2025、投票締切直前! みんなで選んだ歴代の大賞本を振り返って一挙紹介
  3. 3
    Python 3.13の新機能、対話型インタプリタの機能強化や高速化などを解説
  4. 4
    今後生成AIとどう向き合うべきなのか? 現場のエンジニアと研究者が最新研究事例から語り合う
  5. 5
    2024年12月に開催される注目のITエンジニア向けカンファレンス5選
  6. 6
    日本在住の英語を話すソフトウェア開発者、年収の中央値は950万円に
  7. 7
    Vue.js3.4~3.5の新機能をまとめて紹介! 新しいAPIやSSRの改善
  8. 8
    PHPパッケージ管理ツール「Composer」の処理の仕組みを見てみよう!
  9. 9
    高パフォーマンスなコードを書くために不可欠の知識、『なっとく! 並行処理プログラミング』発売
  10. 10
    「CUDA」 ~マンガでプログラミング用語解説

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

メールバックナンバー

アクセスランキング

  1. 1
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説 NEW
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表 NEW
  4. 4
    健全なソフトウェア設計の第一歩! 既存のPHPソースコードからクラス図を自動生成しよう
  5. 5
    開発チームに必要なのは生産性だけじゃない! 健全性も計測し、良い開発者体験を生むために
  1. 6
    VSCodeをUML図やフローチャート作成に使ってみよう
  2. 7
    売上か? 面白い技術か? エンジニア組織が直面するジレンマに、エンジニア経営者 漆原氏が切り込む
  3. 8
    計測と改善をひたすら繰り返したら、年間コストを1億円削減した──不確実性の高いプロジェクトに挑む NEW
  4. 9
    約9割の企業がIT人材不足を実感、「プロリア プログラミング」による調査によって明らかに NEW
  5. 10
    「正解のない仕事」に備える効率的な学び方とは? エンジニアリングマネージャーが認知科学と共に紐解く NEW

アクセスランキング

  1. 1
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説 NEW
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表 NEW
  4. 4
    健全なソフトウェア設計の第一歩! 既存のPHPソースコードからクラス図を自動生成しよう
  5. 5
    開発チームに必要なのは生産性だけじゃない! 健全性も計測し、良い開発者体験を生むために
  6. 6
    VSCodeをUML図やフローチャート作成に使ってみよう
  7. 7
    売上か? 面白い技術か? エンジニア組織が直面するジレンマに、エンジニア経営者 漆原氏が切り込む
  8. 8
    計測と改善をひたすら繰り返したら、年間コストを1億円削減した──不確実性の高いプロジェクトに挑む NEW
  9. 9
    約9割の企業がIT人材不足を実感、「プロリア プログラミング」による調査によって明らかに NEW
  10. 10
    「正解のない仕事」に備える効率的な学び方とは? エンジニアリングマネージャーが認知科学と共に紐解く NEW
  1. 1
    VSCodeをドキュメント作成に活用――テキストエディタ、Markdownエディタの設定と拡張機能を解説
  2. 2
    ITエンジニア本大賞2025、投票締切直前! みんなで選んだ歴代の大賞本を振り返って一挙紹介
  3. 3
    Python 3.13の新機能、対話型インタプリタの機能強化や高速化などを解説
  4. 4
    今後生成AIとどう向き合うべきなのか? 現場のエンジニアと研究者が最新研究事例から語り合う
  5. 5
    2024年12月に開催される注目のITエンジニア向けカンファレンス5選
  6. 6
    日本在住の英語を話すソフトウェア開発者、年収の中央値は950万円に
  7. 7
    Vue.js3.4~3.5の新機能をまとめて紹介! 新しいAPIやSSRの改善
  8. 8
    PHPパッケージ管理ツール「Composer」の処理の仕組みを見てみよう!
  9. 9
    高パフォーマンスなコードを書くために不可欠の知識、『なっとく! 並行処理プログラミング』発売
  10. 10
    「CUDA」 ~マンガでプログラミング用語解説