web-dev-qa-db-ja.com

ハードウェアアクセラレーションによるテキスト処理

グラフィックスプロセッシングユニット(GPU)は非常に一般的であり、浮動小数点数の効率的な並列処理を可能にします。 PPU(Physics Processing Units)は数年前は流行語でしたが、実際に流行ることはなく、この種の計算はGPUでも処理されるようになりました。これらのタイプのハードウェアはどちらも、特定の種類のデータの処理に特化しています。

世界的に開発されているアプリケーションの種類を見ると、それらの多くはテキスト処理に関係しているようです。特にウェブ開発を考える場合。

ハードウェアレベルで基本的な文字列操作(連結、逆転、検索など)、文字レベルの操作を実装することは理にかなっているようです。 CPU。

この種のハードウェアは存在しますか?そうでない場合、何がそれを実行不可能にするのですか?さまざまな長さ?任意のエンコーディング?これらは、浮動小数点数の場合に得られるものと少し似ていると思います(精度はさまざまで、エンコードも異なります)。

一部のベンダーは、テキスト処理/検索を処理するために特別に設計されたデバイスを販売していることを知っています。 Google検索アプライアンスはその一例ですが、私が知る限り、専用ソフトウェアを備えた通常のコンピュータであり、ハードウェアには、テキストを処理するために特別に設計されたプロセッサほどエキゾチックなものはありません。

2
toniedzwiedz

(免責事項:一般的なソフトウェアで見られるさまざまな基本文字列操作の発生率に関する情報はありません。次の回答は、いくつかのポイントに対処するための私の2セントの貢献です。)


簡単な例を挙げると、Intelは文字列操作を高速化するためのSIMD命令を SSE 4.2命令セット(ウィキペディアの記事へのリンク) で提供しています。これらの命令を使用して有用な言語レベルの文字列関数を作成する例は、 このWebサイトで にあります。

これらの指示は何をしますか?

  • 16バイトの文字列フラグメントがある場合(8ビット文字の16カウントまたは16ビット文字の8カウント)、
  • 「等しい」モードでは、同じ長さの別の文字列フラグメントと完全に一致します。
  • 「すべて等しい」モードでは、別の文字列によって指定された文字の小さなセットと一致する文字の出現を強調表示します。例として、英語の単語の母音を検出する「aeiouy」があります。
  • 「範囲比較」モードでは、各文字を1つ以上の文字範囲と比較します。文字範囲の例はazAZで、最初の文字のペアは小文字の英語のアルファベットの範囲を指定し、2番目のペアは大文字のアルファベットを指定します。
  • 「等しい順序」モードでは、部分文字列検索を実行します。

(上記のすべての例は、上記のリンクされたWebサイトから引用したものであり、言い換えがあります。)


このトピックに関するディスカッションを始める前に、そのようなディスカッションに必要な前提知識を収集する必要があります。

以下の大学レベルの入門知識があることを前提としています。

  • CPUアーキテクチャ
  • Verilog やVHDLなどの ハードウェア記述言語 の入門レベルを教えるデジタル設計と合成。
  • そして最後に、上記の知識を使用して何か(たとえば、単純な16ビットALU、乗算器、またはステートマシンに基づくハードウェア入力文字列パターン検出ロジック)を構築し、コストカウントを実行する実践プロジェクト(論理ゲートとシリコン領域)および構築されているもののベンチマーク。

まず、文字列のメモリ内表現のさまざまなスキームを再検討する必要があります。

これは、ハードウェア設計の実習で、ハードウェアの多くのものを「ハードワイヤード」にする必要があることを通知する必要があるためです。ハードウェアは複雑なロジックを実装できますが、それらのロジック間の配線はハードワイヤードです。

この面での私の知識はほとんどありません。しかし、いくつか例を挙げると、 rope 、 "cord"、 "twine"、StringBufferStringBuilder)などはすべてメモリ内の正当な候補です。文字列の表現。

C++だけでも、暗黙の長さの文字列(nullで終了する文字列とも呼ばれます)と明示的な長さの文字列(長さが文字列クラスのフィールドに格納され、文字列が変更されます)。

最後に、一部の言語では、設計者は文字列オブジェクトを不変にすることを決定しています。つまり、文字列を変更したい場合、変更する唯一の方法は次のとおりです。

  • 文字列をコピーして、その場で変更を適用するか、または
  • 元の不変文字列の部分文字列(スライス)を参照し、適用したい変更を宣言します。新しい結果が他のコードによってconsumedされるまで、変更は実際には評価されません

文字列がメモリにどのように割り当てられるかという副次的な質問もあります。


これで、ソフトウェアには多くの素晴らしい(またはクレイジーな)デザインの選択肢が存在することがわかります。これらのさまざまな選択肢をハードウェアに実装する方法については、多くの研究が行われてきました。 (実際、これはデジタルデザインの学位の修士論文を作成するためのお気に入りの方法でした。)

経済的な理由から、ハードウェアベンダーは、文字列がどうあるべきかについての言語/ライブラリ設計者のクレイジーなアイデアをサポートするコストを正当化できないことを除いて、これはすべて問題ありません。

ハードウェアベンダーは通常、世界中のすべての学生(デジタルデザイン)によって書かれたすべての修士論文に完全にアクセスできます。したがって、そのような機能を含めないというハードウェアベンダーの決定は、十分な情報が必要です。


ここで、非常に基本的な常識的な質問に戻りましょう。「一般的なソフトウェアで最も頻繁に実行される文字列操作と、ハードウェアアクセラレーションからどのように利益を得ることができるか」。

難しい数字はありませんが、文字列のコピーを逐語的にはおそらく# 1つの操作が実行されています。

文字列のコピーはすでにハードウェアによって加速されていますか?予想される文字列の長さに依存します。ライブラリコードが数千文字以上の文字列を変更せずにコピーしていることを認識している場合、操作をmemcpyに簡単に変換できます。これは、内部でCPU SIMD(ベクトル化された命令)を使用してメモリを実行します。移動。

さらに、これらの新しいCPUアーキテクチャでは、移動した文字列をCPUキャッシュに保持する(後続の操作のため)か、CPUキャッシュから削除する(キャッシュの汚染を回避する)かを選択できます。

しかし、どのくらいの頻度でそのような長い文字列をコピーする必要がありますか?

標準C++ライブラリは他の場合に最適化する必要があることがわかりました。

つまり、長さが10未満の文字列は非常に高い頻度で発生するため、これらの短い文字列のメモリ管理のオーバーヘッドを最小限に抑えるために特別な場合を行う必要があります。図に行きます。

6
rwong

文字列を並行して操作するには多くの方法があります。テキストデータの操作と分析には、非常に並列的な問題があり、それを多くの文字列に分解します。たとえば、マルチコアプロセッサのスレッド全体に分散させることは、非常に明白な方法です。たとえば、Googleはすべてのテキストをどのように処理しますか?並行して。

多くの検索アルゴリズムがあります ウィキペディア 一度に複数の文字を比較することで恩恵を受けることができます。たとえば、単語の長さを知っていると、それがあなたのベクトルに収まるかどうかを知ることができます。 Xeon Phiプロセッサーは、プロセッサーごとに4つのスレッド、およびチップ上の57または60のプロセッサーコアを間違えていなければ、各プロセッサーには512ビットのベクトルユニットがあります。 Intel-xeon phi 16ビットの32ビット幅の整数を処理できるため、最大フォーマットのUnicode文字を処理できます。パターンが収まる場合は、句読点と空白を適切な距離だけ離して探すことから始めます。いくつかの重複するパターンをチェックしてWordを除外し、そこにあるかどうかを確認し、そのチャンクがパターンと重複しているかどうかを判断します。

57または60コア、512ビットベクトルを使用する4スレッドの倍数は、テキストを操作するための非常に強力なツールです。テキストの大きなチャンクまたは複数のストリームがある場合は、並行して実行します。

出典

0
DeeDeeK