OpenCL で Web アプリケーションを高速化する

ブラウザーでのハイパフォーマンス・コンピューティング

WebCL (Web Computing Language) は、Web アプリケーションがホストのグラフィック・プロセッサー上で関数を実行できるようにすることで、データのソート、テキストの検索、行列システムの解決といった各種のデータ処理ルーチンを飛躍的に高速化します。この記事では、WebCL の JavaScript クラスが計算処理をグラフィック・プロセッサーに実行させることによって、高速な数値演算処理を実現する方法について説明します。

Matthew Scarpino, Software developer, Eclipse Engineering LLC

Matthew Scarpino は、カリフォルニア州マウンテン・ビューに住む、ハイパフォーマンス・グラフィック処理を専門とするソフトウェア開発者です。彼は『OpenCL in Action』と openclblog.com の著者で、現在は、OpenGL と OpenCL を組み合わせたオープンソースのソリッド・モデリング・ツールのコーディングをしています。



2013年 7月 18日

GPU (Graphics Processing Unit: グラフィック・プロセッシング・ユニット) のアーキテクチャーは高度に並列化されていることから、GPU は特定のタイプのアプリケーションを昔ながらの CPU (Central Processing Unit: 中央演算処理装置) よりも遥かに高速に処理することができます。そんな GPU の能力を利用するために最もよく使われている言語の 1 つが、OpenCL (Open Computing Language) です。OpenCL を使用したソフトウェアの著名な例としては、ユーザーのマシンの GPU 上で OpenCL ルーチンを実行することにより、画像および動画の処理を高速化する、Adobe Premiere Pro CS6 があります。

GPU アクセラレーションがブラウザー・ベースのアプリケーションに極めて有効であると判断した数社の企業によって、このテクノロジーを発展させて広く利用できるようにするためのワーキング・グループが結成されました。このワーキング・グループでは 2012年 5月に、WebCL (Web Computing Language) の草案を公開しました。WebCL のメイン・サイト (「参考文献」を参照) で述べられているように、WebCL ワーキング・グループの目的は、「Web アプリケーションが GPU やマルチコア CPU による並列処理を Web ブラウザーから利用」できるようにすることです。

Samsung と Nokia は、ブラウザー内から WebCL の関数を呼び出せるようにする拡張機能をすでにリリースしています。Samsung がリリースした WebKit 用の WebCL 拡張は、Mac OS X 上の Apple Safari ブラウザーを駆動するエンジンです。一方 Nokia は、Windows オペレーティング・システムおよび 32 ビット版 Linux オペレーティング・システム上で実行される Mozilla Firefox 用 WebCL プラグインをリリースしました。この記事では、より広い開発者の基盤を持つ Nokia の実装を中心に、WebCL をインストールする方法と、WebCL コーディングの基礎について説明します。そして最後に、WebCL を使用した高速テキスト検索の例を紹介します。

WebCL のインストール

WebCL アプリケーションを実行するには 3 つのコンポーネントが必要です。その 3 つとは、OpenCL SDK (ソフトウェア開発キット)、Firefox ブラウザー、そして Nokia の Firefox 用プラグインです。

OpenCL SDK を入手する

WebCL アプリケーションは、ホスト・コンピューター上で OpenCL 関数を呼び出します。したがって、WebCL アプリケーションを実行するには、あらかじめ OpenCL をインストールしておく必要があります。OpenCL 開発キットは、デバイスにもオペレーティング・システムにも固有です。そのため、Nvidia GPU を搭載した Windows コンピューター上で OpenCL ルーチンを実行するには、Nvidia のWindows 対応 OpenCL SDK が必要になります。この記事で各種 OpenCL SDK のインストール手順のそれぞれをすべて説明することはできませんが、それぞれの環境で正しくインストールするには以下の内容に従います。

  • AMD の CPU または GPU 上で OpenCL ルーチンを実行するには、AMD APP (Accelerated Parallel Processing) SDK をダウンロードします (「参考文献」のリンクを参照)。
  • Nvidia の GPU 上で OpenCL ルーチンを実行するには、Nvidia GPU Computing SDK をダウンロードします (「参考文献」のリンクを参照)。
  • Intel の CPU 上 OpenCL でルーチンを実行するには、Intel SDK for OpenCL をダウンロードします (「参考文献」のリンクを参照)。

1 台のコンピューターに複数の OpenCL SDK をインストールしても、競合は発生しません。

CPU と GPU

最近の CPU には、「コア」と呼ばれる処理要素がいくつか含まれています。それぞれのコアごとに独自の処理パイプラインとデータ・ストレージがあり、コア同士は、ダイレクト・メモリー・アクセスなどの手段で相互に通信します。マルチコア CPU を使用するようにプログラミングするのは、高度に訓練されたスパイの小規模なチームを率いるようなものです。各メンバーは、それぞれに単独で複雑なミッションを実行することができますが、チームとしてのほうがプロセスの効果が上がります。

一方、GPU の処理はワーク・アイテムによって実行されますが、ワーク・アイテムのメモリーおよび処理リソースには限りがあり、ワーク・アイテムは決定を下すのが得意ではありません。ワーク・アイテム間でのタスクの調整に関しては、さらに不得意です。それでも GPU を使用すると、何千ものワーク・アイテムを同時に処理することができるというメリットがあります。つまり、GPU を使用するようにプログラミングするのは、大規模なゾンビ軍団を率いるようなものです。コマンドが単純である限り、大量の作業をこなすことができます。

WebCL を Firefox にインストールする

OpenCL SDK をインストールした後は、以下の手順で簡単に WebCL をインストールすることができます。

  1. Mozilla サイト (「参考文献」のリンクを参照) から Firefox をダウンロードします。
  2. Firefox で Nokia の WebCL サイト (「参考文献」のリンクを参照) にアクセスし、「WebCL extension for Firefox XX (Firefox XX 用 WebCL 拡張機能)」をクリックします。
  3. 必要に応じて、Firefox が Firefox 拡張機能 (*.xpi ファイル) をダウンロードできるようにします。「Software Installation (ソフトウェアのインストール)」ダイアログ・ボックスで、「Install Now (今すぐインストール)」をクリックします。その後、ブラウザーを再起動します。
  4. インストールが正常に完了したことをテストするには、Nokia の WebCL サイトに移動し、「Click here to check that you have WebCL enabled (WebCL が有効になっていることを確認するには、ここをクリックしてください)」をクリックします。

    「Excellent! Your system does support WebCL (おめでとうございます!ご使用のシステムは WebCL をサポートしています)」というメッセージを示すダイアログ・ボックスが表示されたら、WebCL は正常にインストールされています。ダイアログ・ボックスに「Unfortunately your system does not support WebCL (残念ながら、ご使用のシステムは WebCL をサポートしていません)」と表示された場合は、拡張機能を再インストールするか、別のコンピューターから WebCL にアクセスする必要があります。


WebCL アプリケーションの作成

WebCL の用語は、初めて使用する人にとってはわかりにくい場合があるため、WebCL アプリケーション全体として目指すこと (以下に挙げるような内容) を頭に入れておくことが重要です。

  • 関数をデバイスに渡すこと
  • その関数をデバイス上で実行すること
  • 実行結果としての出力をデバイスからホストに転送すること

図 1 に、このプロセスを示します。

図 1. WebCL アプリケーションの動作
ターゲット・デバイス (GPU) にカーネルをデプロイするホスト・プロセッサー (CPU)

WebCL のクラスと関数

Nokia のツールセットを使用して WebCL アプリケーションを構築する場合、いくつかの JavaScript クラスを十分に理解しておく必要があります。表 1 に、これらのクラスとそれぞれのクラスの重要な関数を記載します。

表 1. WebCL の重要なクラスと関数
クラス目的関数関数の説明
IWebCLプラットフォームとデバイスにアクセスするための静的関数が含まれていますgetPlatformIDs()IWebCLPlatform オブジェクトの配列を返します
createContext(properties, devices)指定されたデバイスが含まれる IWebCLContext オブジェクトを返します
createContextFromType(properties, device_type)指定されたタイプのデバイスが含まれる IWebCLContext オブジェクトを返します
IWebCLPlatformホスト上にインストールされている OpenCL SDK を表しますgetDeviceIDs(device_type)指定されたタイプ (オプション) の IWebCLDevice オブジェクトからなる配列を返します
IWebCLDeviceOpenCL 標準準拠の物理デバイスを表しますgetDeviceInfo(name)デバイスに関する情報を返します
IWebCLContextプログラム、メモリー・オブジェクト、コマンド・キューを管理しますcreateProgramWithSource(source_text)ソース・コードから IWebCLProgram オブジェクトを作成します
createBuffer(flags, size)指定されたサイズのデータを保持するための IWebCLMemoryObject オブジェクトを作成します
createCommandQueue(device, properties)指定されたデバイスにコマンドを渡すための IWebCLCommandQueue オブジェクトを作成します
IWebCLProgram1 つ以上のカーネル関数が含まれるソース・コードbuildProgram(devices, options)指定されたデバイスを対象にプログラムのソース・コードをコンパイルします
createKernel(kernel_name)指定された名前の関数によって IWebCLKernel を作成します
IWebCLKernelOpenCL 対応デバイスで実行できるように特別にコーディングされた関数setKernelArg(index, value, type)メモリー・オブジェクトからカーネル関数の引数を作成します
IWebCLCommandQueueホストとデバイスとの間の通信を可能にしますenqueueReadBuffer(mem_object, blocking, offset, size, data_object, wait_list)デバイスからホストにメモリー・オブジェクトを読み込みます
enqueueWriteBuffer(mem_object, blocking, offset, size, data_object, wait_list)ホストからデバイスにメモリー・オブジェクトを書き込みます
enqueueTask(kernel, wait_list)単一のワーク・アイテムで実行する IWebCLKernel オブジェクトをキューに入れます
enqueueNDRangeKernel(kernel, dim, offset, global_size, local_size, wait_list)複数のワーク・アイテムで実行する IWebCLKernel オブジェクトをキューに入れます

上記のクラスがどのように動作および連動するかを理解するには時間がかかります。けれども、いったん WebCL アプリケーションのコードを作成すれば、わずかな変更を加えるだけで、そのコードを他のアプリケーションにコピー・アンド・ペーストすることができます。

単純なサンプル

ダウンロード」セクションに用意されているサンプル・コードには、完全な WebCL アプリケーションを提供する simple.html というファイルが含まれています。このファイルの JavaScript コードで行われる処理は、ほとんどの WebCL アプリケーションのコードと同様に、以下の 5 つのステップに分けることができます。

  1. WebCL アプリケーションは、まず初めに、カーネル・デプロイメントを管理するための IWebCLContext オブジェクトを作成します。WebCL.createContextFromType 関数は 2 つの引数を取ります。1 つは、列挙された値からなる配列、もう 1 つはコンテキスト内に置かれるデバイスのタイプを識別する値です。アプリケーションのこの部分のコードを以下に示します。
    リスト 1. コンテキストを作成してコンテキスト内のデバイスにアクセスする
    var platforms = WebCL.getPlatformIDs();
    var ctx_props = [WebCL.CL_CONTEXT_PLATFORM, platforms[0]];
    var ctx = WebCL.createContextFromType(ctx_props, WebCL.CL_DEVICE_TYPE_GPU);
    var devices = ctx.getContextInfo(WebCL.CL_CONTEXT_DEVICES);

    上記のコードに示されている CL_DEVICE_TYPE_GPU パラメーターは、コンテキストに GPU デバイスのみを含めることを指定します。最後の行では、コンテキスト内のデバイスが配列の中に配置されています。通常、この配列には、1 つの要素のみが含まれます。それは、ホストの GPU を表す IWebCLDevice です。

  2. コンテキストは、ソース・コードから IWebCLProgram を作成します。すると、アプリケーションがこのプログラムをコンパイルして、カーネル関数のいずれか 1 つから IWebCLKernel を作成します。その方法を以下に示します。
    リスト 2. プログラムをコンパイルしてカーネルを作成する
    var program_src = "__kernel void basic(__global float4* in_vec,     \
                                           __global float4* out_vec) {  \
                           out_vec[0] = in_vec[0];                      \
                       }";
    var program = ctx.createProgramWithSource(program_src);
    program.buildProgram([devices[0]], "");
    var kernel = program.createKernel("basic");

    重要な点として、プログラムとカーネルの違いを理解しておかなければなりません。プログラムはコードの本体であり、1 つ以上の関数を格納します。カーネルは、プログラムのコードに含まれる単一の関数を表します。

  3. カーネルは、basic という関数によって作成されます。この関数が取る引数は、in_vecout_vec の 2 つです。これらの引数は両方ともデバイスのグローバル・アドレス空間に保管されるため、アプリケーションは 2 つの IWebCLMemoryObject (in_buffout_buff) を作成し、これらのオブジェクトをカーネルの引数にします。以下のコードに、その方法を示します。
    リスト 3. メモリー・オブジェクトを作成してカーネルの引数にする
    var in_buff = ctx.createBuffer(WebCL.CL_MEM_READ_ONLY, 16);
    var out_buff = ctx.createBuffer(WebCL.CL_MEM_WRITE_ONLY, 16);
    kernel.setKernelArg(0, in_buff);
    kernel.setKernelArg(1, out_buff);

    createBuffer の引数は、メモリー・オブジェクトのプロパティーを設定します。最初の引数は、カーネル引数が入力を提供するのか (CL_MEM_READ_ONLY)、出力を受け取るのか (CL_MEM_WRITE_ONLY) を明らかにします。createBuffer の 2 番目の引数は、データのサイズをバイト単位で特定します。メモリー・オブジェクトごとに 4 バイトの浮動小数が 4 つ含まれるため、サイズは 16 に設定されています。

  4. カーネルの構成が完了すると、アプリケーションはホストからカーネルにコマンドを転送するための IWebCLCommandQueue を作成します。以下のコードは、コマンド・キューを作成し、データをカーネルの入力引数 (in_vec) に書き込んでから、enqueueTask を呼び出してカーネルを起動します。
    リスト 4. コマンド・キューを作成し、入力データを書き込んでカーネルを起動する
    var queue = ctx.createCommandQueue(devices[0], 0);
    var in_data = new Float32Array([1.5, 2.5, 3.5, 4.5]);
    queue.enqueueWriteBuffer(in_buff, false, 0, 16, in_data, []);
    queue.enqueueTask(kernel, []);

    入力データは 32 ビットの浮動小数点値の配列として指定されています。カーネルのデータを浮動小数点で指定することは必須ではありませんが、値は同様の型が指定された配列 (例えば、Int32ArrayUInt16Array など) に配置しなければなりません。

  5. カーネルが正常に実行されたことを検証するために、アプリケーションは、out_buff メモリー・オブジェクトが設定するカーネルの 2 番目の引数からデータを読み取ります 以下のコードは、out_buff のデータを out_data という配列に読み込み、その配列の内容を Web ページに表示します。
    リスト 5. デバイスからの出力データを読み取り、そのデータをページに表示する
    out_data = new Float32Array(4);
    queue.enqueueReadBuffer(out_buff, true, 0, 16, out_data, []);      
    var output = document.getElementById("output");
    output.innerHTML = "Output: " + out_data[0] + ", " + out_data[1] + ", ";
    output.innerHTML += out_data[2] + ", " + out_data[3];

    このコードは、HTML 文書の output という要素にアクセスすることによって、出力データを表示します。ページの HTML の内容を確認するには、この記事のサンプル・コードをダウンロードして、Firefox で simple.html を開いてください。

ワーク・アイテムと enqueueNDRangeKernel

前のセクションのアプリケーションは、カーネルを実行するために enqueueTask を呼び出しました。WebCL について学んでいる間はこの方法を使用しても問題はありませんが、プロが作成するアプリケーションでこの関数が使用されることは決してありません。なぜなら、enqueueTask は単一のスレッドを使用してカーネルを実行するため、大規模な並列処理を実行する GPU のようなデバイスを使用する目的にそぐわないからです。

WebCL では、処理スレッドはワーク・アイテムと呼ばれます。ワーク・アイテムがどのように使用されるのかを理解するには、リスト 6 に記載するネストされたループを見てください。

リスト 6. 処理スレッド
for(i=a; i<A; i++) {
   for(j=b; j<B; j++) {
      for(k=c; k<C; k++) {
         process_data(i, j, k);
      }
   }
}

process_data 関数は、ijk という 3 つのインデックスを引数に取ります。これらの引数にはそれぞれに異なるオフセット (abc) があり、上限も異なります (ABC)。したがって、インデックスの範囲はそれぞれ、A - aB - bC - c です。OpenCL の用語では、インデックスの範囲をサイズと呼び、インデックスの数を次元と呼びます。つまり、このループには 3 つの次元があり、それぞれの次元のサイズは A - aB - bC - c ということになります。

WebCL を使用する大きなメリットは、時間のかかるループを使用せずに、ワーク・アイテムを使用して process_data のような関数を繰り返し実行できることです。ワーク・アイテムには次元 (12、または 3) があり、そのそれぞれに、ループの個別の繰り返しに対応する一意の ID があります。例えば、複数のワーク・アイテムを 2 つの次元で実行する場合、あるワーク・アイテムは一意の ID (4, 5) のカーネルを実行し、別のワーク・アイテムは ID (5, 4) のカーネルを実行するなどといった具合です。覚えておく必要があるのは、これらのワーク・アイテムはカーネルを並列に実行するということです。

WebCL で複数のワーク・アイテムを構成するには、enqueueTask の代わりに enqueueNDRangeKernel を実行する必要があります。これは、WebCL アプリケーション・プログラミング・インターフェースの中で最も重要な関数です。この関数は以下の 6 つの引数を取ります。

  • kernel ― 実行する関数に対応する IWebCLKernel
  • dim ― 関数を実行するために使用するワーク・アイテムの次元数
  • offsets ― ワーク・アイテムの ID の初期値を格納する配列
  • global_sizes ― 各次元のワーク・アイテムの合計数を格納する配列
  • local_sizes ― 各次元のワーク・グループに含まれるワーク・アイテム数を格納する配列
  • wait_list ― コマンドを実行するにあたって待機しているイベントのリストからなる IWebCLEvent 構造を格納する配列

一例として、リスト 7 のループを検討します。

リスト 7. enqueueNDRangeKernel を構成する
for(i=5; i<50; i++) {
   for(j=6; j<60; j++) {
      for(k=7; k<70; k++) {
         process_data(i, j, k);
      }
   }
}

このループの次元は 3、オフセットは (5、6、7)、ワーク・アイテムのサイズは (45、64、73) です。WebCL を使用して process_data を実行するには、この関数の IWebCLKernel を作成し、そのカーネルを実行するために以下のように enqueueNDRangeKernel を呼び出します。

queue.enqueueTask(kernel, 3, [5, 6, 7], [45, 64, 73], [], []);

最後の 2 つの引数には、空の配列が設定されています。ワーク・グループとイベントは WebCL の魅力的な機能ですが、この記事ではそれらについては説明しません。次のセクションでは、カーネル関数のコーディング方法を説明します。


カーネルのコーディング

WebCL カーネルは、GPU 上やその他の対応するデバイス上で実行されるように意図された関数を表します。その全体的な構造は以下のとおりです。

__kernel void func_name(parameter_list) {
   ...lines of code...
}

各カーネル宣言は __kernel で始まり、その戻り値は常に void です。これは、関数の入力/出力データは、関数のパラメーター・リストによって提供しなければならないことを意味します。カーネル関数のコードは C99 で作成されますが、開発者は WebCL に固有の多数のデータ型および関数にアクセスすることができます。

カーネルのデータ型

カーネルは、C の基本データ型にアクセスし、ベクトル・データ型を使用して極めて高速にデータを処理することができます。これらのデータ型は typen として指定します。ここで、type は基本データ型、n は、ベクトルに含まれるそのデータ型の要素の数です (通常は、2、4、8、または 16)。

例えば、float4 は 4 つの浮動小数が含まれるベクトルです。デバイスが float4 の処理をサポートしている場合は、ベクトルに対する処理を行うごとに、ベクトルのすべての要素が同時に影響を受けますが、サポートしていない場合は、カーネル・コンパイラーがこの処理をデバイスでサポート可能な複数の処理に分割します。

ベクトルを初期化する方法は、配列を初期化する方法と同様ですが、ベクトルの場合には山括弧 ({}) ではなく括弧 (()) を使用します。リスト 8 のコードに、2 つのベクトル (int4 および char16) を宣言して初期化する方法を示します。

リスト 8. 2 つのベクトルを宣言して初期化する
int4 vector_a = (int4)(1, 2, 3, 4);
char16 vector_b = (char16)('H', 'e', 'l', 'l', 'o',
    'P', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'e', 'r', '!');

演算子と数学関数

カーネルは一般に、C で使用されているすべての演算子を使用することができます。つまり、vec_avec_b のベクトルの型が同じである場合、vec_a * vec_b は、それぞれを乗算した積が格納されたベクトルを返します。論理演算子も使用することができ、(5 > 3) が返す値は、カーネルでも通常の関数でも同じです。ベクトルにリレーショナル演算が関わってくる場合、結果が true であればベクトルの要素は -1 に設定され、結果が false であれば 0 に設定されます。

C 関数に数学、ロジック、あるいは比較が伴わなければ、その関数をカーネル内で使用することはおそらく不可能です。ただし、カーネルは、acos から sqrt に至るまで、標準的な数学ライブラリーに含まれるほぼすべての関数を呼び出すことができます。これらの関数は、ベクトルとスカラーのどちらも引数に取ることができます。したがって、vec という float4 の絶対値を計算するには、vec が単なる別の数字であるかのように、fabs(vec) を呼び出すことになります。

ワーク・アイテム関数

ワーク・アイテムがカーネルを実行するときの最初のタスクには、通常、自身の ID を決定することが含まれます。さらに、カーネルの次元、カーネルを実行するワーク・アイテムの合計数にアクセスする場合もあります。それには、以下の関数を使用します。

  • get_global_id(int i) ― 次元 i でのワーク・アイテムの ID を返します。
  • get_work_dim() ― カーネルを実行するワーク・アイテムの次元数を返します。
  • get_global_size(int i) ― 次元 i でカーネルを実行するワーク・アイテムの数を返します。

リスト 9 に記載するカーネル関数に、ワーク・アイテム関数を実際に使用する方法を示します。

リスト 9. ワーク・アイテム関数の実例
__kernel void example(__global float* in_array, __global float* out_array) {
   int id = get_global_id(0);
   int N = get_global_size(0);
   out_array[id] = in_array[id]/N; 
}

このカーネルを実行するワーク・アイテムの次元数は 1 で、in_arrayout_array の要素ごとに 1 つのワーク・アイテムがあります。カーネルが実行されると、各ワーク・アイテムが in_array の要素を読み取り、それをワーク・アイテムの合計数で割った値を out_array に保管します。要するに、これが WebCL カーネルが動作する仕組みです。次のセクションでは、これと同様のプロセスを使用してテキストを検索します。


WebCL を使用したテキスト検索

多くの Web アプリケーションでは、大量のテキストの中から可能な限り短時間でパターンを検出しなければなりません。このようなタイプのアプリケーションは、大量のデータを力ずくで処理することを専門とする GPU に最適です。サンプルの text_search プロジェクトは、Amy Lowell (エイミー・ローウェル) の叙事詩「The Great Adventure of Max Breuck」で 4 つの単語 (that、very、time、および more) を検索します。図 2 に、その方法を示します。

図 2. OpenCL ベクトルによるテキスト検索
入力テキストとパターンの比較

このアルゴリズムを実装するために使用したファイルは、以下の 3 つです。これらのファイルは、この記事に付属のダウンロード可能なアーカイブに含まれています。

  • text_search.html ― Web ページの HTML と、カーネルをデプロイする JavaScript が含まれます。
  • text_search.cl ― Web ページの HTML と、カーネルをデプロイする JavaScript が含まれます。
  • poem.txt ― 詩のテキストがそのままの状態で含まれます (ファイルの始めと終わりに、追加の文字が挿入されています)。

各ワーク・アイテムは詩の 16 文字を読み取り、4 つの単語それぞれの有無をチェックします。一致が検出されると、ワーク・アイテムは、ホストに返される 4 つのカウンターのうちの 1 つをアトミックに増分します。リスト 10 に、この関数を記載します。

リスト 10. テキスト検索カウンターを増分する関数
		__kernel void text_search(__global char* text,
                          __global int* match_count) {

   char16 pattern = (char16)('t', 'h', 'a', 't', 'v', 'e', 'r', 'y', 
                             't', 'i', 'm', 'e', 'm', 'o', 'r', 'e');
   char16 test_vector, check_vector;

   /* load global text into private buffer */
   test_vector = vload16(0, text + get_global_id(0));

   /* compare test vector and pattern */
   check_vector = test_vector == pattern;

   /* Check for 'that,' 'very,' 'time,' and 'more' */
   if(all(check_vector.s0123))
      atomic_inc(match_count);
   if(all(check_vector.s4567))
      atomic_inc(match_count + 1);
   if(all(check_vector.s89AB))
      atomic_inc(match_count + 2);
   if(all(check_vector.sCDEF))
      atomic_inc(match_count + 3);
}

図 3 に、Firefox に出力されたカーネルの実行結果を示します。

図 3. テキスト検索の結果
Amy Lowell (エイミー・ローウェル) の詩に含まれる 4 つの単語の数

結果は、grep ユーティリティーで検証することができます。例えば、コマンド grep -o time poem.txt を実行すると、poem.txt ファイル内で「time」という単語が出現した回数が返されます。

text_search ホスト・アプリケーションがカーネルを実行するために生成するワーク・アイテムの数は 30,865 です。GPU によっては、一度にすべてのワーク・アイテムが実行されるわけではないこともありますが、それは重要な問題ではありません。ワーク・アイテムのあるグループが実行を完了すると同時に、別のグループが代わって実行されます。したがって、「実行できるワーク・アイテムの数は?」というよくある質問に対する答えは、「必要な数だけ実行できます」です。


まとめ: WebCL の今後

WebCL がどれだけの能力を提供するかを考えると、利用できるブラウザー拡張機能がこれほど少ないことが奇妙に思えるかもしれません。問題は、セキュリティーにあります。カーネルを実行すると、無限ループやデッドロックなどのエラーが発生する可能性があります。これは CPU にとっては大きな問題ではありませんが、私のこれまでの経験では、GPU エラーによってコンピューターがフリーズする恐れがあります。その場合、Ctrl-C や Ctrl-Alt-Delete は助けにならず、システムを再起動しなければならなくなります。

この問題を是正するために、GPU メーカーはそれぞれのオファリングのセキュリティーを強化することを約束しています。つまり、システムをクラッシュさせることなく、ユーザーが GPU の実行を中断または停止できるようにするということです。この機能が一般的に使われるようになれば、WebCL は一風変わった存在から、不可欠な技術に変わるはずです。WebCL による高速実行では、ブラウザー・アプリケーションがデータの処理とグラフィックのレンダリングにおいて、通常のデスクトップ・アプリケーションと同じパフォーマンスを実現できるようになるはずです。


ダウンロード

内容ファイル名サイズ
Example code for WebCL developmentwebcl_src.zip10KB

参考文献

学ぶために

  • WebCL Working Draft: このワーキング・ドラフトに、WebCL に関する進展の現状が表れています。
  • OpenCL ドキュメント: このオンライン・ドキュメントに、OpenCL アプリケーションで使用される関数とデータ構造が記載されています。
  • 「Gentle Introduction to OpenCL」: Dr. Dobbs のこの記事では、OpenCL アプリケーションの動作に関する基本的な概要を説明しています。
  • OpenCLサイト: Khronos.org の OpenCL サイトでは、OpenCL 開発に関するニュースと情報を提供しています。
  • Web development ゾーン: Web 2.0、Ajax、Wiki、PHP、マッシュアップ、そしてその他の Web プロジェクトの資料が用意されています。
  • developerWorks コミュニティー: developerWorks のエクスペリエンスを自分流にカスタマイズしてください。
  • developerWorks のテクニカル・イベント: これらのセッションで最新の技術情報を入手してください。
  • Twitter での developerWorks: 今すぐ登録して developerWorks のツイートをフォローしてください。
  • developerWorks podcast: ソフトウェア開発者向けの興味深いインタビューやディスカッションを聴いてください。
  • developerWorks オンデマンド・デモ: 初心者向けの製品のインストールおよびセットアップから熟練開発者向けの高度な機能に至るまで、さまざまに揃ったデモを見てください。

製品や技術を入手するために

  • APP SDK: AMD デバイス上でカーネルを実行するには、AMD の APP SDK をダウンロードしてください。
  • GPU Computing SDK: Nvidia デバイス上でカーネルを実行するには、Nvidia の SDK をダウンロードしてください。
  • OpenCL SDK: Intel デバイス上でカーネルを実行するには、Intel の SDK をダウンロードしてください。
  • Firefox: Mozilla Foundation から Firefox の最新バージョンをダウンロードしてください。
  • Nokia の WebCL 実装: Nokia の Firefox 向けの WebCL 実装をダウンロードしてください。
  • Samsung WebCL プロトタイプ: Samsung の WebKit ブラウザー・エンジンのプロトタイプをダウンロードしてください。
  • IBM 製品の評価版: DB2、Lotus、Rational、Tivoli、および WebSphere のアプリケーション開発ツールやミドルウェア製品を体験するには、評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版を試してみてください。

議論するために

  • developerWorks コミュニティー: ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者によるブログ、フォーラム、グループ、Wiki を調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=937049
ArticleTitle=OpenCL で Web アプリケーションを高速化する
publish-date=07182013