Microsoft Word - paper.docx

Similar documents
07-二村幸孝・出口大輔.indd

GPGPUによる高速画像処理

Microsoft PowerPoint - pr_12_template-bs.pptx

1. GPU コンピューティング GPU コンピューティング GPUによる 汎用コンピューティング GPU = Graphics Processing Unit CUDA Compute Unified Device Architecture NVIDIA の GPU コンピューティング環境 Lin

Microsoft PowerPoint - GPGPU実践基礎工学(web).pptx

Slide 1

熊本大学学術リポジトリ Kumamoto University Repositor Title GPGPU による高速演算について Author(s) 榎本, 昌一 Citation Issue date Type URL Presentation

GPU のアーキテクチャとプログラム構造 長岡技術科学大学電気電子情報工学専攻出川智啓

TSUBAME2.0におけるGPUの 活用方法

GPU.....

main.dvi

CUDA を用いた画像処理 画像処理を CUDA で並列化 基本的な並列化の考え方 目標 : 妥当な Naïve コードが書ける 最適化の初歩がわかる ブロックサイズ メモリアクセスパターン

Slides: TimeGraph: GPU Scheduling for Real-Time Multi-Tasking Environments

( CUDA CUDA CUDA CUDA ( NVIDIA CUDA I

プログラミング実習I

C#の基本

インテル(R) Visual Fortran コンパイラ 10.0

PowerPoint プレゼンテーション

Microsoft PowerPoint - GPGPU実践基礎工学(web).pptx

SICE東北支部研究集会資料(2013年)

NUMAの構成

CUDA 連携とライブラリの活用 2

1 GPU GPGPU GPU CPU 2 GPU 2007 NVIDIA GPGPU CUDA[3] GPGPU CUDA GPGPU CUDA GPGPU GPU GPU GPU Graphics Processing Unit LSI LSI CPU ( ) DRAM GPU LSI GPU

ゲームプログラミング講習 第0章 導入

memo

大域照明計算手法開発のためのレンダリングフレームワーク Lightmetrica: 拡張 検証に特化した研究開発のためレンダラ 図 1: Lightmetrica を用いてレンダリングした画像例 シーンは拡散反射面 光沢面を含み 複数の面光 源を用いて ピンホールカメラを用いてレンダリングを行った

Prog1_6th

数はファイル内のどの関数からでも参照できるので便利ではありますが 変数の衝突が起こったり ファイル内のどこで値が書き換えられたかわかりづらくなったりなどの欠点があります 複数の関数で変数を共有する時は出来るだけ引数を使うようにし グローバル変数は プログラムの全体の状態を表すものなど最低限のものに留

目次 はじめに 4 概要 4 背景 4 対象 5 スケジュール 5 目標点 6 使用機材 6 第 1 章 C# 言語 7 C# 言語の歴史 7 基本構文 8 C 言語との違い 9 Java 言語との違い 10.Netフレームワーク 10 開発資料 10 第 2 章 Mono 11 Monoの歴史 1

コンピュータグラフィックス基礎              No

Prog1_10th

PowerPoint Presentation

Microsoft PowerPoint - kougi7.ppt

3次多項式パラメタ推定計算の CUDAを用いた実装 (CUDAプログラミングの練習として) Implementation of the Estimation of the parameters of 3rd-order-Polynomial with CUDA

Slide 1

プログラミング実習I

Microsoft Word - 3new.doc

Fortran 勉強会 第 5 回 辻野智紀

研究報告用MS-Wordテンプレートファイル

TSUBAME2.0 における GPU の 活用方法 東京工業大学学術国際情報センター丸山直也第 10 回 GPU コンピューティング講習会 2011 年 9 月 28 日

Microsoft PowerPoint - 11.pptx

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

スライド 1

1. マシンビジョンにおける GPU の活用

PowerPoint Presentation

PowerPoint プレゼンテーション

Source Insight

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

AquesTalk プログラミングガイド

System Requirements for Geomagic

Taro-ポインタ変数Ⅰ(公開版).j

Microsoft PowerPoint - kougi2.ppt

Microsoft PowerPoint - 12.ppt [互換モード]

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

PowerPoint プレゼンテーション

2006年10月5日(木)実施

Microsoft PowerPoint - prog03.ppt

PowerPoint プレゼンテーション

Microsoft PowerPoint - 計算機言語 第7回.ppt

統合開発環境CubeSuite+ V へのバージョンアップのお知らせ

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

JDK のインストール (2012 年 8 月時点でのバージョン ) Java の実行環境 開発環境は さまざまな企業 団体が開発 配布を行っているが 当テキストでは Java の生みの親である Sun MicroSystems 社 ( 現 Oracle 社 ) の実行環境 開発環境を使用する Ja

Microsoft Word - Training10_プリプロセッサ.docx

N08

Microsoft Word - no02.doc

NEC Express5800 シリーズ COBOL Enterprise Edition クライアントライセンス V1 COBOL Enterprise Edition クライアントライセンス V1 (1 年間保守付き ) COBOL Enterprise Edition クライアントライセンス

TopSE並行システム はじめに

Prog1_6th

Microsoft Word - nvsi_050110jp_netvault_vtl_on_dothill_sannetII.doc

Microsoft Word - HOKUSAI_system_overview_ja.docx

Microsoft PowerPoint - 13.ppt [互換モード]

講習No.1

2. 30 Visual Words TF-IDF Lowe [4] Scale-Invarient Feature Transform (SIFT) Bay [1] Speeded Up Robust Features (SURF) SIFT 128 SURF 64 Visual Words Ni

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

PowerPoint Presentation

Prog1_12th

Microsoft PowerPoint - kougi9.ppt

3/7 マイグレーション開発方針 顧客名 0 作成者 根岸正 < プログラム移行方針 > システム名称 A-VX システムマイグレーション作成日 2015/09/01 < COBOL 資産のプログラム移行 > COBOLソース ( メインとCOPYLIB) を入力としてSCC 言語変換ツールにてVB

IPSJ SIG Technical Report Vol.2013-ARC-203 No /2/1 SMYLE OpenCL (NEDO) IT FPGA SMYLEref SMYLE OpenCL SMYLE OpenCL FPGA 1

kiso2-03.key

Microsoft PowerPoint - ICD2011UenoSlides.pptx

Microsoft Word ●IntelクアッドコアCPUでのベンチマーク_吉岡_ _更新__ doc

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

02: 変数と標準入出力

24th Embarcadero Developer Camp

EnSightのご紹介

PowerPoint プレゼンテーション

AN1526 RX開発環境の使用方法(CS+、Renesas Flash Programmer)

PowerPoint プレゼンテーション

Microsoft PowerPoint - OpenMP入門.pptx

実習を行う上での心構えについて

27_02.indd

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

program7app.ppt

スライド 1

ex04_2012.ppt

kantan_C_1_iro3.indd

Microsoft PowerPoint - ca ppt [互換モード]

型名 RF007 ラジオコミュニケーションテスタ Radio Communication Tester ソフトウェア開発キット マニュアル アールエフネットワーク株式会社 RFnetworks Corporation RF007SDK-M001 RF007SDK-M001 参考資料 1

Transcription:

による高速画像処理 名古屋大学大学院情報科学研究科出口大輔, 井手一郎, 村瀬洋 概要 : 本発表では, 近年注目を集めている GP(General Purpose computing on s) の技術に着目し,GP を利用するための開発環境の使い方やプログラミングのノウハウを分かりやすく解説する. GP は を汎用計算に利用しようという試みであり, 現在では物理シミュレーション, 数値計算, 信号解析, 画像処理 認識などの分野で広く利用されるようになっている. ここ数年では,GP を行うための開発環境の整備も進んできている. そこで本発表では,NVIDIA 社が提供している開発環境の CUDA を題材に取り上げ, 簡単に GP を行うことができることを示すと供に, 計算コストの高い画像処理が を利用することで大幅に高速化できることを示す. 1. はじめに近年の の高性能化に伴い, を汎用計算に利用しようという試みである GP が注目を集めている. 図 1 は 2003 年 ~2008 年に発売された と の性能差を GFLOP/s(1 秒あたりの浮動小数点演算性能 ) で表したものである. 図から分かるように,2003 年頃は と の差はそれほど大きくはないが,2008 年にはその差が約 10 倍程度に広がっている. また, は非常に高性能であるにもかかわらず, GeForce GTX 285( 現在発売されている の中で最も高性能なものの一つ ) は 4 万円 ~5 万円程度で購入することができる. このように, 非常に高性能な を安価に入手できるようになった点も,GP の技術が注目される大きな要因となっている. このように, と比較して非常に高性能な をグラフィックス以外の処理へ利用しようという試みは,2003 年にプログラマブルシェーダが登場して以降, 広く行われるようになった [1][2]. これは, プログラマブルシェーダを利用することにより 上でプログラムを比較的簡単に動作させることが可能になったためである. しかしながら, プログラマブルシェーダを利用する 1000 [GFLOP/s] 900 800 700 600 500 400 300 200 100 Geforece 8800GTX Geforece GTX280 Core2 Duo 3.0GHz NVIDIA Quad Core Xeon 3.2GHz Intel 0 2003 年 2004 年 2005 年 2006 年 2007 年 2008 年 1900 1900 1900 1900 1900 1900 1900 図 1 と の性能比較 [3] ためにはグラフィックスパイプラインを強く意識したプログラミングが必要なため,GP の敷居は必ずしも低くなかった. この問題を解決するため,GP を行うための開発環境の整備が進んでおり,NVIDIA 社の CUDA,AMD 社の ATI Stream などが利用できるようになっている. これらの開発環境では, グラフィックスパイプラインを意識することなく が利用できるため, 非常に簡単に GP を行うことが可能である. そこで本稿では, 開発環境として NVIDIA 社の CUDA を取り上げ,CUDA でプログラミングを行う際に必要となる環境構築方法, およびプログラミング時の注意点を分かりやすく解説する. また, 計算コストの高い画像処理が を利用することで簡単に高速化できることを示す.

2. CUDA の環境構築本節では, まず CUDA の概要を説明した後, CUDA を実行するために必要となる環境 (OS, グラフィックスカードなど ),CUDA を実行するために必要となるソフトウェアの導入方法を順に説明する. 2.1 CUDA とは? NVIDIA 社が提供する CUDA は Compute Unified Device Architecture の略であり,C/C++ 言語を利用して の処理を記述することができる統合開発環境である. 従来,GP を行うためには,HLSL や GLSL といったシェーダ言語を利用する必要があり, グラフィックスパイプラインを強く意識したプログラミングが必要であった. そのため, グラフィックス処理に合わせたアルゴリズムの変更が必要不可欠であり, これが GP の敷居を高くしていた大きな原因であった. これに対し,CUDA では通常の C/C++ 言語の関数を呼び出す ( で処理を行う ) 感覚で を利用できるようになっている. そのため, グラフィックスパイプラインに関する知識は不要であり,C/C++ 言語を学習したことのある研究者や開発者であれば比較的容易に GP を行うことが可能になっている. また,C/C++ 言語を用いて GP を行うことが可能であるため, 既存のアルゴリズムの移植も容易であるという特徴がある. 以下では,CUDA を利用するための準備段階として, 環境の構築方法を説明する. 2.2 実行環境の準備 CUDA を利用するためには, 表 1 に示す NVIDIA 社製のグラフィックスカードを用意する必要がある. 例えば,GeForce GTX 285 はコンシューマー向けのグラフィックスカードの中ではかなり高性能なものであり, その性能は約 1 TFLOP/s である.GeForce GTX 285 は非常に高性能ではあるが, その市場価格は 4 万円 ~5 万円程度であるため, 比較的容易に入手できるのではないだろうか. また,Quadro シリーズはワーク 表 1 CUDA 対応のグラフィックスカード GTX 280, GTX 260, 9800 シリ GeForce ーズ, 8800 シリーズ, 他 Quadro Tesla Plex 2200 D2, FX 5800, FX 5600, 他 S1070, C1060, S870, D870, C870 ステーション等で利用されている非常に高価なグラフィックスカードであるが, GeForce シリーズと大きな性能差は無い ( ただし, 搭載されているメモリ量は Quadro シリーズの方が多い ). そして,Tesla は CUDA を実行するための専用ハードウェアであり, ビデオ出力は搭載されていない. 初めて GP に挑戦するのであれば, 安価な GeForce シリーズがお勧めである. CUDA が対応している OS は,Windows XP, Windows Vista, Windows Server 2008, Windows 7,Linux,Mac OS であり, 現在広く普及しているさまざまな OS 上で実行することが可能である. 本稿では説明の都合上,Windows をメインの実行環境として説明を行う.Linux や Mac を使われている方々は,CUDA Zone [4] を参考に環境構築を行っていただきたい. 2.3 開発環境の準備 CUDA を利用して のプログラムを作成するためには,2.1 で説明したハードウェアの準備に加え, 本節で述べる開発環境の準備が必要となる. まず,CUDA Zone [4] へアクセスし,CUDA Driver,CUDA Toolkit,CUDA SDK をダウンロードしよう.CUDA Driver は CUDA 対応のビデオドライバーであり,CUDA 上でプログラムを動作させるために必要なものである.CUDA で作成したプログラムを配布する際には, 配布先でも CUDA 対応のビデオドライバーが必要になるので注意が必要である.CUDA Toolkit は CUDA の開発で利用する nvcc コンパイラや CUBLAS や CUFFT といった数値計算ライブラリ, プログラミングガイド等のドキュメントが含まれている.

図 2 カスタムビルド規則 の選択 図 3 Cuda.Rules の追加 図 4 NVCC のコンパイルオプション CUDA で開発を行う際は必ず必要になるため, ドライバーと併せてインストールして欲しい. 最後に,CUDA SDK には CUDA を利用する上で非常に参考になる多くのサンプルプログラムがソース付きで収録されている. 初めて CUDA に触れる際は, 一通り目を通すことを強くお勧めする. また,Visual Studio を使って CUDA のプログラ ムを開発する際に有用なツールである Cuda.Rules も含まれている. そのため,CUDA Driver と Toolkit に加えて SDK もインストールしておくことをお勧めする. 本稿の執筆時点 (2009 年 8 月 ) では,CUDA のバージョンは 2.3 である. 以降は, バージョン 2.3 を利用して話を進める. 2.4 Visual Studio の設定 Visual Studio は Microsoft 社が販売している統合開発環境であり, 世界中で多くの研究者 開発者が利用しているツールである. そこで, 本節では CUDA の開発を Visual Studio で行う際の設定方法を説明する. まず本節を読み進める前に,2.3 で述べた CUDA SDK のインストールを済ませて欲しい. Visual Studio の新規作成画面から Visual C++ の Win32 コンソールアプリケーションもしくは Win32 プロジェクトを作成する. そして, 図 2 に示すプロジェクトメニューから カスタムビルド規則 を選択し, 図 3 の 既存ファイルの検索 を実行する. その際,CUDA SDK に含まれる Cuda.Rules を選択しよう. これらの操作により, 図 4 に示すようなプログラムをコンパイルする際のオプションを Visual Studio 上で設定できるようになる. ただし, これらのオプションはファイルの拡張子が.cu のものに対してのみ有効であるので注意が必要である. プロジェクトをビルドする際は, 追加のライブラリパスに $(CUDA_LIB_PATH) を設定し,cuda.lib と cudart.lib の 2 つを追加の依存ファイルに設定する. これにより,CUDA が利用可能になる. 3. CUDA のプログラミングモデル CUDA は, を多数のが高い並列性を持って処理を実行できるデバイスとして扱う. は数百ものを並列に処理することが可能なため,CUDA にはを階層的に管理する仕組みが導入されている. また, 上に実装された特殊なメモリ領域へのアクセス

方法や, 間の同期, といった機能も簡単に利用できるようになっている. 以下では CUDA でプログラムを書く前段階として,CUDA の管理の仕組み,CUDA のメモリモデルについて説明する. 3.1 管理の仕組み CUDA では, 図 5 に示すようにブロックとグリッドの 2 つの階層でを管理する. 具体的には, のまとまりをブロックと呼び, ブロックのまとまりをグリッドと呼ぶ. また, およびブロックは 3 次元的に配置することが可能であり, 各および各ブロックは X, Y,Z の 3 つの整数の組で一意に識別される. つまり, 各および各ブロックの ID は (1, 0, 0) や (1, 2, 3) のように表される. そして,CUDA ではグリッドを一つの単位として処理を実行する. 具体的には, 図 6 に示すように処理毎にとブロックの数を決定して処理を実行する. また, の処理結果を 側で利用する場合は, と の同期をとった後でメモリ転送が必要となる. これらの管理の機構は の構成と密接な関係があり, 同じブロック内の同士でしか処理の同期ができない ( ブロック間での同期をとる場合は の処理が必要 ) といった制限が存在する. これらの詳細に関しては文献 [3] を参照されたい. 3.2 メモリモデル には でプログラムを書く場合には利用しない, 特殊なメモリ領域がいくつか存在する. 具体的に が利用できるメモリは, レジスタ, ローカルメモリ, 共有メモリ, コンスタントメモリ, テクスチャメモリ, グローバルメモリ, の 6 種類である ( 図 7). これらのメモリは大きく分けて,(1) 内でのみ利用可能なメモリ,(2) ブロック内ので共有されるメモリ,(3) すべてので共有されるメモリ, の 3 つに分けられる. レジスタとローカルメモリは (1) に対応し, 共有メモリが (2) に対応する. それ グリッド ブロック (0,0,0) (0,0,1) (0,0,0) (0,0,1) (1,0,0) (0,1,0) (0,1,1) ブロック (0,1,1) (2,0,0) (0,2,0) (0,2,1) (0,1,0) (1,0,0) (1,0,1) (1,1,1) (2,1,0) (1,2,0) (1,2,1) ブロック (1,0,0) (1,0,1) (0,0,0) (0,0,1) (1,0,0) (0,1,0) (0,1,1) (2,0,0) (0,2,0) (0,2,1) (0,1,0) (1,0,0) (1,0,1) (1,1,1) ブロック (1,1,1) ブロック (0,1,0) ブロック 処理 1 処理 2 図 6 ブロック (0,0,0) 図 5 階層的な管理 グリッド 1 ブロック (0,0,0) ブロック (1,0,0) (0,0,0) (0,1,0) (1,0,0) (2,0,0) (2,1,0) (0,0,0) (0,1,0) ブロック (0,1,0) ブロック グリッド 2 ブロック (0,0,0) ブロック (1,0,0) 共有メモリローカルメモリローカルメモリ レジスタ (0,0,0) (2,1,0) (1,2,0) (1,2,1) (1,0,0) CUDA における計算の流れ レジスタ (1,0,0) ブロック (1,0,0) コンスタントメモリ テクスチャメモリ グローバルメモリ (2,0,0) (2,1,0) 共有メモリローカルメモリローカルメモリ レジスタ レジスタ (0,0,0) (1,0,0) 図 7 CUDA のメモリモデル 以外は (3) となる. 使用するメモリによっては間で共有できないものもあるため注意が必要である. また各メモリ領域は, メモリ量, アクセス速度, キャッシュの有無, などに違いが存在するため, 目的に応じて使用するメモリを適切に選択する必要がある. 例えば, グローバルメモリは大容量であるが,1 回のメモリアクセスに 400~600 クロックサイクルが必要である. そのため,Coalesced メモリアクセスの考慮が必要となる. これらの詳細は文献 [3] を参照されたい. CUDA で利用可能な 6 種類のメモリの内, テクスチャメモリは に特有のメモリ領域である.

1: #include <stdio.h> 2: 3: global void hello( char *data ) 4: { 5: char *text = "Hello World!! n"; 6: data[ threadidx.x ] = text[ threadidx.x ]; 7: } 8: 9: int main( int argc, char *argv[] ) 10: { 11: char *ddata, hdata[ 14 ]; 12: cudamalloc( ( void ** )&ddata, sizeof( char ) * 5 ); 13: 14: dim3 nthreads( 14, 1 ); 15: dim3 nblocks( 1, 1 ); 16: hello<<< nblocks, nthreads >>>( ddata ); 17: 18: cudamemcpy( hdata, ddata, 14, cudamemcpydevicetohost ); 19: 20: for( int i = 0 ; i < 14 ; i++ ) 21: { 22: printf( "%c", hdata[ i ] ); 23: } 24: 25: cudafree( ddata ); 26: return( 0 ); 27: } 図 8 CUDA で Hello World!! テクスチャメモリでは,2 次元テクスチャに対して効率の良いキャッシュ機構や, ハードウェア線形補間, といった に無い機能を利用することができる. 画像処理のアルゴリズムを高速化する上で, テクスチャメモリは非常に使いやすく重宝するメモリ領域である. 具体的な使い方は以降の節を参照していただきたい. 4. CUDA で Hello World!! 本節では,Hello World!! をサンプルとして利用し,CUDA における基本的なプログラミング方法を紹介する. 図 8 は CUDA を利用して 上で Hello World!! を計算するプログラム例である. 本プログラムをテキストエディタに入力し, hello.cu という名前で保存しよう ( 拡張子.cu は 上で実行されるコードを含むファイルを グリッド ブロック (0,0,0) (0,0,1) (0,0,1) (0,1,1) (0,2,1) (0,0,0) (1,0,0) (0,1,0) (2,0,0) (0,2,0) (1,0,1) (1,1,1) (1,2,1) (0,1,0) (1,0,0) ブロック (0,1,1) blockidx (2,1,0) (1,2,0) ブロック (1,0,0) (1,0,1) blockdim (0,0,1) (0,1,1) (0,2,1) = (0,0,0) (0,0,0) 3 2 2 (1,0,0) (0,1,0) (2,0,0) (0,2,0) (1,0,1) (1,1,1) (1,2,1) (0,1,0) (1,0,0) ブロック (1,1,1) threadidx ブロック (0,1,0) ブロック (2,1,0) (1,2,0) griddim = 2 2 2 図 9 数とブロック数の取得方法 表す拡張子である ). そして Visual Studio 2008 コマンドプロンプト を立ち上げ, nvcc hello.cu と打ち込むと Hello World!! を表示するプログラムが生成される. もちろん,2.4 で設定した Visual Studio のプロジェクトを用いても Hello World!! をコンパイルすることができる. 生成されたプログラムを実行すると, コンソールに Hello World!! と表示されるはずである. 一見, 通常の C/C++ のプログラムと変わらないように思われるかもしれないが, 本プログラムには CUDA で を利用する際に必要となる重要な点がいくつか含まれている. 以下でそれらの具体的な説明を行う. 図 8 をよく見ると, global や threadidxといった通常の C/C++ 言語では見慣れない記号がいくつか含まれていることが分かる. これらは,CUDA で を利用するために行った C/C++ 言語の拡張部分である. まず, global は から呼び出され 上で実行される関数を表す修飾子である. device や host なども存在するが, それらの詳細は文献 [3] に譲る. そして, global が付与された関数を から呼び出す際は, 図 8 の 16 行目のように関数名と引数の間に <<< >>> で囲まれたパラメータを指定する. これは,3.1 で説明したとブロックの配置方法を指定するものである. 具体的には,14~15 行目で設定した数とブロック数により 上で生成される配置が決定される. このように, で実行される関数を から呼び出す際は, 生成する数を指定して関数を呼び

出す必要がある点に注意が必要である. 上の各は,6 行目の threadidx という組み込み変数を参照することで, 自身の ID(X,Y, Z の 3 つの整数の組 ) を把握することができる. threadidx 以外にも, 図 9 に示すような変数を用いることでブロックの ID(blockIdx), ブロック内の数 (blockdim), グリッド内のブロック数 (griddim) を取得することができる. これらの変数は各の計算範囲を決定するために利用することができる. 最後に, からは 上のメモリ ( 主記憶 ) にアクセスできないという制限がある. そのため, 上で利用するメモリ領域は別途確保する必要がある. これを行っているのが図 8 の 12 行目である. また, と で処理するデータを共有する場合は,18 行目の cudamemcpy 関数を利用して互いにメモリ転送を行う必要がある. ただし, 使用するメモリ領域によっては異なる関数を使用する必要があるため, 文献 [3] をよく読んでから利用して欲しい. 本操作は でプログラムを書く際には意識する必要のないものである. そのため, で処理を実行する場合はどのメモリ領域を利用しているかに関して十分な注意が必要である. 5. テンプレートマッチングの実装テンプレートマッチングは画像処理の分野で広く用いられている基本的な手法であり, 基盤の品質検査や画像中の特定物体 ( 人物など ) の検出に利用されている. テンプレートマッチングは, 入力画像中に窓を設定し, その窓の大きさと位置を変化させながらテンプレートとの類似度を評価することで最もテンプレートに類似する部分を見つける処理である. しかしながら, 窓の位置と大きさをさまざまに変化させながら類似度評価を行うため, 膨大な数の類似度評価が必要となる. そのため, 一般的にテンプレートマッチングをリアルタイムで動かすことは難しく, これまでにさまざまな高速化手法 [5] が提案されている. 本節では, 実時間で動作させることの難しかったテ スケール図 10 複数スケールのテンプレート ンプレートマッチングを 上に実装し, リアルタイムに動作させる方法を説明する. 5.1 高速化の基本戦略テンプレートマッチングでは, 類似度の評価は窓単位で独立に行うことが可能である. これは, 膨大な数の処理を同時に実行できる に適した問題である. そこで, 各窓の類似度評価を 上の各が行うことにより, 類似度評価の並列化を図る. テンプレートマッチングには, 隣り合う窓同士はほぼ同じ部分画像 ( メモリ領域 ) にアクセスするという特徴がある. そのため,3.2 で説明した大容量のグローバルメモリを利用する場合は, メモリアクセスが大きなボトルネックとなる. そこで, 本節では 特有の機能であるテクスチャメモリを用いることでメモリアクセスの効率化を図る. テクスチャメモリは読み取り専用のメモリ領域ではあるが,2 次元画像に対して効率的にキャッシュが可能な機構を備えている. このキャッシュ機構を利用することによりメモリアクセスの高速化を図る. また, テンプレートマッチングでは窓の大きさを変化させながら類似度評価を行うため, 図 10 のように複数スケールのテンプレートを事前に用意する必要がある. 本節では, 複数スケールのテンプレートを事前に用意する代わりに, テクスチャメモリの正規化座標を利用することでスケールの変化に対応する. 以下では, 具体的なテンプレートマッチングの実装方法を示す. 5.2 実装方法まず, テンプレートマッチングで利用するテンプレートおよび入力画像をテクスチャメモリに

1: texture< uchar4, 2, cudareadmodeelementtype > imgtex; 2: texture< uchar4, 2, cudareadmodenormalizedfloat > reftex; 3: 4: global void kernel( /* 引数は省略 */ ) 5: { 6: int i = threadidx.x + blockdim.x * blockidx.x; 7: int j = threadidx.y + blockdim.y * blockidx.y; 8: 9: float err = 0.0f; 10: 11: if( i < areaw && j < areah ) 12: { 13: float _1_w = 1.0f / maskw; 14: float _1_h = 1.0f / maskh; 15: for( int n = 0 ; n < maskh ; n++ ) 16: { 17: for( int m = 0 ; m < maskw ; m++ ) 18: { 19: uchar4 p1 = tex2d( imgtex, i + m, j + n ); 20: float4 p2 = tex2d( reftex, _1_w * m, _1_h * n ) * 255.0f; 21: err += ( p1.x - p2.x ) * ( p1.x - p2.x ); 22: err += ( p1.y - p2.y ) * ( p1.y - p2.y ); 23: err += ( p1.z - p2.z ) * ( p1.z - p2.z ); 24: } 25: } 26: 27: err *= _1_w * _1_h; 28: if( error[ i + j * imgw ] > err ) 29: { 30: error[ i + j * imgw ] = err; 31: scale[ i + j * imgw ] = s; 32: } 33: } 34: } 35: 36: // 側に入力画像用のメモリ領域を確保する 37: cudaarray *iarray; 38: cudachannelformatdesc c1 = cudacreatechanneldesc< uchar4 >( ); 39: cudamallocarray( &iarray, &c1, 画像の幅, 画像の高さ ); 40: cudamemcpytoarray( iarray, 0, 0, 入力画像のポインタ, 入力画像のバイト数, cudamemcpyhosttodevice ); 41: cudabindtexturetoarray( imgtex, iarray, c1 ); 42: 43: // 側にテンプレート画像用のメモリ領域を確保する 44: cudaarray *rarray; 45: cudachannelformatdesc c2 = cudacreatechanneldesc< uchar4 >( ); 46: cudamallocarray( &rarray, &c2, 画像の幅, 画像の高さ ); 47: cudamemcpytoarray( rarray, 0, 0, テンプレートのポインタ, テンプレートのバイト数, cudamemcpyhosttodevice ); 48: cudabindtexturetoarray( reftex, rarray, c2 ); 49: 50: // 正規化座標を有効にする 51: reftex.filtermode = cudafiltermodelinear; 52: reftex.normalized = 1; 図 11 テンプレートマッチングの主要部確保するための準備を行う. テクスチャメモリを利用するためには, texture<type, Dim, ReadMode> 変数名 ; によりテクスチャメモリを表す変数を一つ用意する必要がある. ここで,Type はテクスチャ内の各画素の型であり int,float,int3,float4 等が指定可能である. また,Dim はテクスチャの次元を表し,1~3 のいずれかを指定する. そして, ReadMode はテクスチャメモリからの読み出し時に値を正規化するかどうかを示すフラグである.cudaReadModeElementType を指定した場合は各データ型に対応した値が返され, cudareadmodenormalizedfloat を指定した場合は値が 0~1 の範囲に正規化される (Type が符号付きの場合は -1~1). 今回は 2 次元画像が対象であるため,Type に uchar4,dim に 2 を指定している ( 図 11 の 1~2 行目 ). 図 11 の 36~48 行目が 上のメモリ領域の確保とテクスチャメモリへのマッピングを行う部分である. そして,50~52 行目により正規化座標を有効にしている. ここで, 図 12 は正規化座標を有効にした場合としない場合の違いを示している. 図 12 と図 13 から分かるように, 正規化座標を有効にすることで, 画像の大きさにかかわらず 0~1 の範囲でアクセスできることが分かる. これにより, スケールに依存しないメモリアクセスが可能となる. 今回はこの機能を利用することでマルチテンプレートと同等の機能を実現する. (0, 0) (W-1, 0) (0, H-1) (W-1, H-1) (0, 0) (1, 0) (0, 1) (1, 1) 図 12 正規化座標の有効 / 無効による違い. ( 左 ) 有効でない場合,( 右 ) 有効な場合. (0, 0) (1, 0) (0, 1) (0, 0) (1, 0) (0, 1) 図 13 正規化座標を利用したメモリアクセス

テクスチャメモリへのアクセスは非常に簡単であり, 図 11 の 19~20 行目のように tex2d にテクスチャメモリを指す変数と座標を指定する. ただし,tex2D の戻り値はテクスチャの定義 (Type と ReadMode の組み合わせ ) に依存するため注意が必要である. 最後に, 図 11 の 4~34 行目が入力画像とテンプレート間の類似度を計算する部分である. 今回は SSD(Sum of Squared Difference) を利用し, 上の各がこの関数を実行する方法を採用する. ここで, 各がどの位置を計算するかは 6~7 行目で決定している. これは, 入力画像を図 14 右のような 16 16 のブロックで 16 16 (threadidx.y, threadidx.x) (blockidx.y, blockidx.x) 図 14 各の計算位置 図 15 テンプレート画像 図 16 実験結果 分割し, 各ブロック内の各画素を 上の各が計算する方法である. この方法は非常に単純ではあるが, さまざまな場面で利用できる有効な分割方法である. また, からこの関数を呼び出す際は,3.1 で説明したの階層が図 14 に従うように設定する必要がある. 5.3 計算速度の評価上記で説明したプログラムを計算機上に実装し, と の計算速度を比較した. 使用した計算機は, : Intel Core2 Quad Q9550(2.83 GHz), : NVIDIA GeForce GTX280 である. には 4 つのコアが搭載されているため,OpenMP [6] を利用して 4 で並列計算するようにプログラムを実装した. また, には 30 基のマルチプロセッサ (1 基あたり 8 個のスカラープロセッサが内蔵されている ) が搭載されている. 入力画像は 800 600 画素である. また, 図 15 は実験に用いたテンプレート画像であり, 大きさは 105 135 画素である. また, スケールに関しては 0.3~1.8 倍 ( 拡大率 1.2) とした. 上に実装したテンプレートマッチングを実行した結果を図 16 に示す. 図中の枠で囲まれた部分が最もテンプレートに類似する部分であり, テンプレートと同じ物体が正しく枠で囲まれていることが分かる. また, は処理に約 48.7 秒必要であったが, は約 2.0 秒で処理が終了した. この結果から, を利用することで約 24 倍の高速化が得られることを確認した. 6. SIFT の実装近年, 回転やスケールに対して頑健な特徴である SIFT(Scale Invariant Feature Transform) が注目を集めている [7][8]. 特に,SIFT の特長を活かした画像間のマッチングや物体認識 検出に関する研究が盛んである. しかしながら,SIFT は複数スケールで DOG(Difference Of Gaussian) の計算が必要なため, 実時間での処理が難しいと

いう問題があった. そこで, 本節では SIFT を 上に実装した場合にどの程度の高速化が得られるかを示す. 本節では SIFT を に実装する際の基本的な考え方の説明のみを行い, 具体的な実装方法は文献 [9] に譲る. 6.1 高速化の基本戦略 SIFT の実装において最も計算コストの高い処理の一つが DOG である.DOG の計算の大部分は, 2 次元ガウシアンフィルタの処理に費やされる. ここで,2 次元ガウシアンフィルタは 1 次元ガウシアンフィルタの畳み込みで表現することができる. この性質を利用し,1 次元ガウシアンフィルタを X 軸方向と Y 軸方向に適用することで 2 次元ガウシアンフィルタの高速化を行う. 本処理では,1 次元テクスチャを効果的に使うことでメモリアクセスの効率化を図ることが可能である. また,DOG 画像からのキーポイント検出は画素単位で行うことが可能なため, キーポイント検出は を用いて容易に高速化可能である. 処理の流れを図 17 にまとめる. 図に示すように,SIFT } Ø Ø 入力画像 2100 2000 1900 1800 1700 1600 1500 1400 1300 1200 1100 1000 900 800 700 600 500 400 300 200 100 0 [msec.] Þ ƒ Ÿ f Ý ã Ó DoG 画像 Ü á Û ã Þ ƒ キーポイント Ü á Û ã â Ý 図 17 処理の流れ (SIFT) 計算時間 (N 2 = 600 2 の場合 ) : 458.0 msec. : 10.2 msec. ( 44.9) Þ ƒ Ü âü ã Ý ã f オリエンテーション 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000 画像サイズ N 2 計算時間 (SIFT) 図 18 を実装する際は と の処理をうまく切り分ける必要がある点に注意が必要である. 6.2 計算速度の評価 5.3 で用いた計算機上に SIFT を実装し, と それぞれの計算時間を評価した. 入力画像サイズを 50 50~1000 1000 の範囲で変化させた場合の計算時間を図 18 に示す. 図から分かるように, を利用することで約 45 倍 ( 画像サイズが 600 600 の場合 ) の高速化が得られ, SIFT をリアルタイムで計算可能なことを確認した. 今回はキーポイントの検出とオリエンテーションの算出までを 上に実装したが, 興味のある人は SIFT 特徴量の実装にも挑戦していただきたい. 7. むすび本稿では, 近年注目を集めている GP の紹介を行った. また, 開発環境として CUDA を利用し,GP を非常に簡単に行えることを示した. そして, を用いることで計算コストの高い画像処理アルゴリズムを容易に高速化できることを示した. しかしながら, すべての画像処理アルゴリズムを で高速化できるとはかぎらない. 一般的に, 空間フィルタリングや局所特徴量の計算は での高速化が容易であるが, ラベリングや細線化といった逐次型の画像処理アルゴリズムは高速化が困難である. また, CUDA で複数の を利用する際は, 各 を操作する を別途用意する必要がある. そのため, 複数 の利用には OS の管理に関する知識が少しばかり必要となる. 今後, 複数の を簡単に扱えるようなフレームワークが登場することを期待したい. 最後に, 本稿を読まれた読者が GP に少しでも興味を持っていただければ幸いである. 謝辞 日頃より熱心に御討論頂く名古屋大学村瀬研究室諸氏に深く感謝する. 特に, プログラムの作成等で協力いただいた, 名古屋大学の二村幸孝先生, 野田雅文君に深く感謝する.

参考文献 [1] M. J. Harris, G. Coombe, T. Scheuermann, and A. Lastra, Physically-Based Visual Simulation on Graphics Hardware, Proceedings of SIGGRAPH 2002 / Eurographics Workshop on Graphics Hardware 2002, pp.1-10, 2002. [2] J. D. Owens, D. Luebke, N. Govindaraju, M. Harris, J. Krüger, A. E. Lefohn, and T. J. Purcell, A Survey of General-Purpose Computation on Graphics Hardware, Computer Graphics Forum, Vol.26, No.1, pp.80-113, 2007. [3] CUDA Programming Guide, http://www.nvidia.com/object/cuda_develop.html [4] CUDA ZONE, http://www.nvidia.com/object/cuda_home.html [5] 村瀬洋,V. V. Vinod, 局所色情報を用いた高速物体探索 -- アクティブ探索法 -- (Fast visual search using focussed color matching - active search -), 電子情報通信学会論文誌,Vol. J81-DII,No.9, pp.2035-2042,1998. [6] OpenMP, http://openmp.org/ [7] David G. Lowe, Distinctive image features from scale-invariant keypoints, International Journal of Computer Vision, 60, 2, pp. 91-110, 2004. [8] 藤吉弘, Gradient ベースの特徴抽出 -SIFT と HOG-, 情報処理学会研究報告, CVIM 160,pp. 211-224,2007. [9] Sift: A Implementation of SIFT, http://www.cs.unc.edu/~ccwu/siftgpu/