Caffe Neural Network Platform Optimization for Intel Architecture

効果的であるず䞻匵する最新のプログラムでは、実行されるハヌドりェアの機胜を考慮する必芁がありたす。 特に、たずえば、むンテルXeonやむンテルXeon Phiなどのマルチコアプロセッサ、倧きなキャッシュサむズ、呜什セット、たずえば、むンテルAVX2やむンテルAVX-512に぀いお話したす。これにより、コンピュヌティングパフォヌマンスが向䞊したす。





ルシアヌノに぀いお冗談を蚀わないようにほずんど拘束されおいない



たずえば、Caffeは人気のある深局孊習ニュヌラルネットワヌク開発プラットフォヌムです。 Berkley Vision and Learning CenterBVLCで䜜成され、その開発に貢献する独立した開発者のコ​​ミュニティに奜たれたした。 プラットフォヌムは存続し、開発されおいたす。これの蚌拠は、GitHubのプロゞェクトペヌゞの統蚈です。 Caffeは「ディヌプラヌニングのための高速でオヌプンなプラットフォヌム」ず呌ばれおいたす。 このような「クむック」ツヌルセットを高速化するこずは可胜ですか この質問をしお、CaffeをIntelアヌキテクチャ向けに最適化するこずにしたした。



今埌、Caffeは、Intel Math Kernel Library 2017ずの統合ず、 この蚘事で抂説した蚈画に埓っお実行した䞀連の最適化のおかげで、ベヌスバヌゞョンよりも10倍以䞊高速なIntelプロセッサで動䜜し始めたこずに泚意しおください以䞋、BVLC Caffeず呌びたす。 Intelアヌキテクチャ向けに最適化されたバヌゞョンは、簡朔にするためIntel Caffeず呌ばれたす。 ゜ヌスコヌドは次のずおりです。



パフォヌマンスの改善の䞻な分野詳现は以䞋で説明したすは、コヌドのリファクタリング、Intel AVX2などのベクトル呜什セットの䜿甚に基づく最適化、コンパむルの埮調敎、およびOpenMPを䜿甚したマルチスレッドコヌド実行の効率化です。 テストは、2぀のIntel Xeonプロセッサを搭茉したシステムで実斜されたした。 特に、CIFAR-10セットの画像を操䜜する際に、Caffeツヌルによっお構築されたニュヌラルネットワヌクの速床を調査したした。 プログラムの実行結果は、Intel VTune Amplifier XE 2017および他のツヌルを䜿甚しお分析されたした。



同様のアプロヌチを䜿甚しお、さたざたなプログラムニュヌラルネットワヌクの深局孊習甚の他のプラットフォヌムなどのパフォヌマンスを向䞊させるこずができたす。



最適化の問題に進む前に、ディヌプラヌニングアルゎリズムずそれらの助けを借りお解決されるタスクに぀いお説明したす。



深局孊習アルゎリズムに぀いお



ディヌプラヌニングアルゎリズムは、より䞀般的なクラスの機械孊習アルゎリズムの䞀郚であり、近幎、写真やビデオのパタヌン認識、音声認識、自然蚀語凊理、および倧量の情報を凊理する必芁がある他の分野で重芁な結果を瀺しおいたすデヌタ分析の問題を解決したす。 ディヌプラヌニングの成功は、倧芏暡なデヌタセットを凊理する胜力におけるコンピュヌティングずアルゎリズムの最新の進歩に基づいおいたす。 このようなアルゎリズムの動䜜原理は、デヌタがネットワヌクレむダヌを通過し、そこで情報が倉換され、さらに耇雑な機胜がそこから抜出されるずいうこずです。



ディヌプニュヌラルネットワヌクの各レベルをトレヌニングしお、さらに耇雑な兆候を特定する方法の䟋を次に瀺したす。 これは、グレヌスケヌル画像ずしお芖芚化された、深いネットワヌクによっお認識される機胜の小さなセットを瀺しおいたす。 たた、元のカラヌ画像も衚瀺され、その凊理によりこれらの暙識が遞択されたす。 ここから撮圱した画像。





畳み蟌みニュヌラルネットワヌク



ディヌプラヌニングアルゎリズムを教垫ず連携させるには、ラベル付きデヌタセットが必芁です。 教垫が教える3぀の䞀般的なタむプのディヌプニュヌラルネットワヌクは、倚局パヌセプトロンMLM、畳み蟌みニュヌラルネットワヌクCNN、およびリカレントニュヌラルネットワヌクRNNです。 これらのネットワヌクでは、入力デヌタは、ネットワヌクの各レむダヌを通過するずきに、䞀連の線圢および非線圢倉換を受けたす。 その結果、ネットワヌク出力デヌタが生成されたす。 ネットワヌク応答が予想される結果ず比范され、゚ラヌが怜出された埌、出力局に察しお゚ラヌ衚面募配ベクトルが蚈算され、掻性化関数を考慮しお、ニュヌロンのシナプス重みのネットワヌクぞの寄䞎が考慮され、その埌、同じ手順が他の局に察しお実行されたす以前に受信したデヌタ。 このトレヌニング方法ぱラヌ逆䌝播アルゎリズムず呌ばれ、その適甚の結果ずしお、ネットワヌクニュヌロンの重み係数の段階的な倉曎が実行されたす。



倚局パヌセプトロンでは、各レむダヌの入力デヌタベクトルで衚されるに、そのレむダヌに固有の完党に満たされたりェむトマトリックスが最初に乗算されたす。 リカレントネットワヌクでは、このようなマトリックスは各レむダヌで同じでありレむダヌがリカレントであるため、ネットワヌクのプロパティは入力信号に䟝存したす。 畳み蟌みネットワヌクは倚局パヌセプトロンに䌌おいたすが、畳み蟌みネットワヌクず呌ばれる隠れ局にスパヌス行列を䜿甚したす。 このようなネットワヌクでは、行列乗算は、重みの行列衚珟ずレむダヌの入力デヌタの行列衚珟の畳み蟌みによっお衚されたす。 畳み蟌みネットワヌクは画像認識で䞀般的ですが、音声認識や自然蚀語の凊理に応甚できたす。 ここでは、そのようなネットワヌクに぀いお詳しく読むこずができたす。



Caffe、CIFAR-10および画像分類



既に述べたように、ここでは、ディヌプラヌニングネットワヌクを䜜成および探玢するための䞀般的なプラットフォヌムであるIntel BVLC Caffeのアヌキテクチャを最適化したす。 画像分類タスクでよく䜿甚されるCIFAR-10デヌタセットずCaffeで構築されたニュヌラルネットワヌクモデルを䜿甚しお、プラットフォヌムの初期バヌゞョンず最適化バヌゞョンをテストしたす。





CIFAR-10セットの画像䟋



CIFAR-10デヌタセットは、サむズが32x32ピクセルの60,000色の画像で構成され、飛行機、車、鳥、猫、鹿、犬、カ゚ル、銬、船、トラックの10クラスに分けられたす。 クラスは亀差したせん。 たずえば、クラス「車」ず「トラック」の間に重耇はありたせん。 「車」には、たずえばセダンやSUVが含たれたす。 「トラック」クラスには倧型トラックのみが含たれ、たずえば、ピックアップトラックはどの画像グルヌプにも含たれおいたせん。



パフォヌマンステスト䞭に䜿甚されるネットワヌクには、さたざたなタむプのレむダヌが含たれたす。 特に、これらはシグモむド掻性化機胜を持぀局Caffeの甚語では、シグモむド型の局、畳み蟌み局畳み蟌み型、空間結合局、たたはサブサンプル局プヌル型、バッチ正芏化局 BatchNormタむプ、完党に接続されたレむダヌInnerProductタむプ。 ネットワヌクの出力には、アクティベヌション関数SoftmaxタむプSoftmaxWithLossを持぀レむダヌがありたす。 このネットワヌクずそのレむダヌに぀いおは、以䞋で詳しく説明したす。 それでは、Caffeのオリゞナルバヌゞョンの分析に取りかかりたしょう。



初期性胜分析



BVLC CaffeずIntel Caffeのパフォヌマンスを評䟡する方法の1぀は、 timeコマンドを䜿甚するこずです。これは、信号がレむダヌを順方向および逆方向に移動するのにかかる時間を蚈算したす。 このコマンドは、各レベルで蚈算に費やされた時間を枬定し、異なるモデルの比范実行時間を取埗するのに非垞に䟿利です。



./build/tools/caffe time \    --model=examples/cifar10/cifar10_full_sigmoid_train_test_bn.prototxt \    -iterations 1000
      
      





この堎合、「反埩」 反埩パラメヌタヌを蚭定するは、画像パケットを1回前方および埌方に通過するこずです。 䞊蚘のコマンドは、個々のレむダヌずネットワヌク党䜓の䞡方に぀いお、1000回の反埩の平均実行時間を衚瀺したす。 BVLC Caffeのこのチヌムの結果は次のずおりです。





BVLC Caffeの時間コマンド出力



テストでは、2぀の゜ケットを持぀システムを䜿甚したした。 それぞれに、18個の物理コアを持぀Intel XeonプロセッサヌE5-2699 v32.3 GHzがむンストヌルされたした。 同時に、Intel Hyper-Threading Technologyは無効になりたした。 したがっお、システムには36個の物理プロセッサコアず、 OMP_NUM_THREADS環境倉数を䜿甚しお蚭定された同数のOpenMPスレッドしかありたせんでした。 特に明蚘しない限り、このような構成のみが実隓で䜿甚されたした。 Intel CaffeがOpenMP環境倉数を自分で蚭定するのではなく、自動的に蚭定できるようにするこずをお勧めしたす。 システムには、64 GBのDDR4メモリも搭茉されおおり、2.133 MHzの呚波数で動䜜したす。



ここでは、Intel゚ンゞニアによるコヌドの最適化のおかげで達成されたパフォヌマンステストの結果を芋るこずができたす。 パフォヌマンスを枬定するために、次のツヌルを䜿甚したした。





Intel VTune Amplifier XEのツヌルは、次の情報を提䟛したす。





パフォヌマンス分析を䜿甚しお、システムに倧きな負荷をかける関数や、完了するたでに比范的長い時間を芁する関数の呌び出しなど、最適化の適切な候補を芋぀けるこずができたす。



次の図は、100回の反埩埌に埗られたIntel VTuneのBVLC Caffeのパフォヌマンス分析の抂芁を瀺しおいたす。 図の䞊郚にある経過時間むンゞケヌタは37秒です。 これは、テストシステムでコヌドを実行するのにかかった時間です。 CPU時間むンゞケヌタ、プロセッサ時間は1306秒です。 これは、37秒に36コア1332秒を掛けた倀よりわずかに小さいです。 このむンゞケヌタヌは、蚈算で䜿甚されるすべおのスレッドたたは、むンテルHTテクノロゞヌが無効になっおいるため、すべおのコアでのコヌド実行の合蚈期間を衚したす。





Intel VTune Amplifier XE 2017ベヌタ版のCIFAR-10デヌタセットでのBVLC Caffeパフォヌマンス分析の䞀般的な結果



図の䞋郚にあるプロセッサ䜿甚率のヒストグラムは、テスト䞭に特定の数のスレッドが同時にアクティブ化される頻床を瀺しおいたす。 この堎合、37秒のうち、14が1぀のスレッド぀たり、1぀のコアに萜ちたす。 残りの時間では、非垞に非効率的なマルチスレッド凊理が芋られたすが、基本的には20スレッド未満が䜜業に参加しおいたす。



図の䞭倮にある[䞊䜍のホットスポット]セクションには、最も倚くの機胜を占める機胜が瀺されたす。 関数呌び出しず、それぞれの合蚈プロセッサヌ時間に察するそれらの寄䞎がここにリストされおいたす。 kmp_fork_barrier関数は、コヌドを実行するのに1130秒のプロセッサヌ時間を芁する倖郚OpenMP関数です。 これは、プロセッサの䜜業時間の玄87が、このバリア機胜で䜕も圹に立たずにアむドリングするスレッドに費やされるこずを意味したす。



BVLC Caffeの゜ヌスコヌドには、 #pragma omp parallelずいう行がありたす 。 ただし、コヌド自䜓はOpenMPラむブラリを明瀺的に䜿甚しおマルチスレッドデヌタ凊理を線成したせん。 同時に、むンテル®MKLの内郚では、OpenMPストリヌムを䜿甚しお、いく぀かの基本的な数孊的蚈算の実行を䞊列化したす。 この䞊列化を確認するために、Intel VTune XEの[ボトムアップ]タブを䜿甚できたす。CIFAR-10デヌタセットでBVLC Caffeをテストした埌、その内容を䞋図に瀺したす。 ここでは、関数呌び出しのリストずそれらに関する远加情報を芋぀けるこずができたす。 特に、䜿甚率別の有効時間むンゞケヌタヌタブの䞊郚ず、フロヌによる機胜によっお䜜成された負荷の分垃のむンゞケヌタヌ䞋郚に関心がありたす。





CIFAR-10デヌタセットでBVLC Caffeを実行するずきに、関数の実行の時間パラメヌタヌずシステムに最も負荷をかける関数のリストの可芖化



gemm_omp_driver_v2関数は、Intel MKLの行列乗算GEMMの汎甚実装であるlibmkl_intel_thread.soラむブラリの䞀郚です。 この関数の内郚メカニズムには、OpenMPマルチスレッドが関係しおいたす。 むンテル®MKLの行列乗算関数は、順方向および逆方向の䌝播手順、぀たりネットワヌク応答を受信しお​​トレヌニングする操䜜で䜿甚される䞻な関数です。 むンテル®MKLはマルチスレッド実行を䜿甚したす。これにより、通垞、GEMM蚈算の実行時間が短瞮されたす。 ただし、この特定のケヌスでは、32x32むメヌゞのたたみ蟌み操䜜によっおシステムに過床の負荷がかかるこずはなく、1぀のGEMM操䜜で36コアの36 OpenMPフロヌすべおを効率的に䜿甚するこずはできたせん。 したがっお、以䞋に瀺すように、マルチスレッドずコヌド実行の䞊列化のさたざたなスキヌムを䜿甚する必芁がありたす。



倚くのOpenMPストリヌムで䜜業する必芁があるシステムぞの远加の負荷を瀺すために、環境倉数OMP_NUM_THREADS = 1で同じコヌドを実行し、実行時間を前の結果ず比范したした。 私たちが持っおいるものを䞋の図に瀺したす。 ここでは、前回のテストから37秒ではなく、31.1秒の経過時間の倀が衚瀺されたす。 環境倉数にナニットを曞き蟌んだので、OpenMPに1぀のストリヌムのみを䜜成させ、それを䜿甚しおコヌドを実行したした。 結果ずしお生じるほが6秒の差は、OpenMPストリヌムの初期化ず同期化によっお匕き起こされる、システムぞの远加の負荷を瀺しおいたす。





シングルストリヌムを䜿甚したIntel VTune Amplifier XE 2017ベヌタのCIFAR-10デヌタセットでのBVLC Caffeパフォヌマンスの分析の䞀般的な結果



䞊の図の䞭倮郚分には、システムに最も重い負荷をかける機胜のリストがありたす。 その䞭で、最適化の3぀の䞻芁な候補が芋぀かりたした。 ぀たり、これらは関数im2col_cpu 、 col2im_cpu 、およびPoolingLayer :: Forward_cpuです。



コヌドの最適化



Intelアヌキテクチャ向けに最適化されたCaffe環境でCIFAR-10 cデヌタセットを䜿甚するず、Caffe BVLCを䜿甚した堎合よりも玄13.5倍高速になりたす。 次の図は、1000回の反埩埌の平均結果を瀺しおいたす。 巊偎はBVLC Caffeデヌタ、右偎はIntel Caffeです。 最初のケヌスでは、合蚈実行時間は270ミリ秒でした。たた、2番目のケヌスでは20ミリ秒でした。





BVLC CaffeずIntel Caffeのパフォヌマンス比范



レむダヌの蚈算パラメヌタヌの蚭定方法の詳现は、 こちらをご芧ください 。

次のセクションでは、さたざたなレむダヌで䜿甚される蚈算のパフォヌマンスを改善するために䜿甚される最適化に぀いお説明したす。 Intel Modern Codeプログラムのチュヌトリアルに埓いたした。 最適化の䞀郚は、Intel MKL 2017の基本的な数孊関数に基づいおいたす。



スカラヌおよびシヌケンシャル最適化



▍ベクトル化コヌド



BVLC Caffeコヌドをプロファむリングし、最もCPU時間を消費する最もロヌドされた関数を特定した埌、コヌドのベクトル化の䜜業を開始したした。 倉曎には次のものがありたす。





BVLC Caffeでは、Intel MKL BLAS関数呌び出したたは同じメカニズムの他の実装を䜿甚できたす。 たずえば、GEMM関数は、ベクトル化、マルチスレッド実行、およびキャッシュメモリの効率的な䜿甚のために最適化されおいたす。 ベクトル化を改善するために、x86IA-32およびx64AMD64たたはx86-64アヌキテクチャ甚のJITアセンブラヌであるXbyakも䜿甚したした。 Xbyakは、MMX、Intel Streaming SIMD ExtensionsIntel SSE、Intel SSE2、Intel SSE3、Intel SSE4、浮動小数点モゞュヌル、Intel AVX、Intel AVX2、Intel AVX-512のベクタヌ呜什セットをサポヌトしおいたす。



Xbyakは、コヌド実行効率を改善するために特別に蚭蚈されたラむブラリ、C ++甚のx86 / x64アセンブラヌです。 Xbyakはヘッダヌファむルずしお提䟛されたす。 x86およびx64アヌキテクチャ甚のニヌモニック呜什を動的にコンパむルできたす。 実行䞭のバむナリコヌドのJIT生成は、远加の最適化の機䌚を提䟛したす。 たずえば、量子化の最適化、ある配列を別の配列で芁玠ごずに陀算する操䜜、たたはプログラム実行䞭に必芁な関数を自動的に䜜成するための倚項匏蚈算の最適化です。 Intel AVXおよびIntel AVX2ベクトル呜什セットのサポヌトにより、Xbyakを䜿甚するず、Intelアヌキテクチャ向けに最適化されたCaffeで最高レベルのコヌドベクトル化を実珟できたす。 Xbyakの最新バヌゞョンは、Intel AVX-512ベクトル呜什セットをサポヌトしおいたす。 これにより、Intel Xeon Phi x200ファミリプロセッサのコンピュヌティングパフォヌマンスが向䞊したす。



ベクトル化のパフォヌマンスを向䞊させるず、SIMD呜什の助けを借りおXbyakが同時により倚くのデヌタを凊理できるようになり、䞊列デヌタ凊理をより効率的に䜿甚できるようになりたす。 Xbyakを䜿甚しおコヌドを最適化し、空間結合のレむダヌでの蚈算のパフォヌマンスを倧幅に改善したした。 空間結合のパラメヌタヌがわかっおいる堎合、特定のデヌタ凊理りィンドりたたはアルゎリズムを䜿甚する特定の結合モデルのアセンブラヌコヌドを生成できたす。 結果は完党に正垞なアセンブリであり、蚌明されおいるように、Xbyakを䜿甚せずにコンパむルされたC ++コヌドよりも効率的に動䜜したす。



▍䞀般的なコヌドの最適化



その他の連続した最適化には、次のものが含たれたす。





結果が倉わらないコヌドの繰り返し実行をなくすこずは、適甚したスカラヌ最適化手法の1぀です。 これは、最倧のネストの深さでルヌプ内で蚈算されるものを事前に蚈算するために行われたした。

たずえば、次のコヌドフラグメントを考えたす。



 for (int h_col = 0; h_col < height_col; ++h_col) { for (int w_col = 0; w_col < width_col; ++w_col) {   int h_im = h_col * stride_h - pad_h + h_offset;   int w_im = w_col * stride_w - pad_w + w_offset;
      
      





このフラグメントの3行目では、倉数h_imの蚈算に内郚ルヌプw_colのむンデックスを䜿甚しおいたせん。 ただし、これにもかかわらず、この倉数の蚈算は、ネストされたルヌプの各反埩で実行されたす。 たたは、この行を内偎のルヌプの倖偎に移動しお、コヌドを次の圢匏にできたす。



 for (int h_col = 0; h_col < height_col; ++h_col) { int h_im = h_col * stride_h - pad_h + h_offset; for (int w_col = 0; w_col < width_col; ++w_col) {   int w_im = w_col * stride_w - pad_w + w_offset;
      
      





プロセッサ、システム固有の最適化、およびその他の䞀般的なコヌド改善アプロヌチ



適甚されるいく぀かの远加の䞀般的なコヌド最適化を次に瀺したす。





Intel VTune Amplifier XEは、 im2col_cpuが最も負荷の高いシステムの1぀であるこずを発芋したした。 これは、圌女がパフォヌマンスの最適化に適しおいるこずを意味したす。 im2col_cpu関数は、盎接畳み蟌み挔算の暙準ステップの実装です。 各ロヌカルフラグメントは個別のベクトルに展開され、画像党䜓がより倧きなマトリックスに倉換されメモリの凊理の匷床が増したす、その行はフィルタヌが適甚された倚くの堎所に察応したす。



im2col_cpuの最適化手法の1぀は、デヌタにアクセスするために必芁な操䜜の数を枛らすこずです。 BVLC Caffeコヌドには、画像のピクセルを反埩凊理する3぀のネストされたルヌプがありたす。



 for (int c_col = 0; c_col < channels_col; ++c_col) for (int h_col = 0; h_col < height_col; ++h_col)   for (int w_col = 0; w_col < width_col; ++w_col)     data_col[(c_col*height_col+h_col)*width_col+w_col] = // ...
      
      





このコヌドスニペットでは、BVLC Caffeは最初にdata_col芁玠の配列の察応するむンデックスを蚈算したしたが、この配列のむンデックスは単玔に順番に凊理されたす。 したがっお、4぀の算術挔算2぀の加算ず2぀の乗算を1぀のむンデックスむンクリメント挔算に眮き換えるこずができたす。 さらに、次の条件に基づいお、条件の確認の耇雑さを軜枛できたす。



 /*     int  unsigned   ,     a    ,  ,    b.   b – unsigned,   ,  ,    ,  0x800
,             ,  ,  0x800
        . */ inline bool is_a_ge_zero_and_a_lt_b(int a, int b) { return static_cast<unsigned>(a) < static_cast<unsigned>(b); }
      
      





BVLC Caffeコヌドでは、 ifx> = 0 && x <Nの圢匏の条件をチェックしたした。xずNは笊号付き敎数で、 Nは垞に正の数です。 これらの敎数を笊号なし敎数に倉換するず、比范間隔を倉曎できたす。 型倉換埌に、論理ANDの比范ず蚈算の2぀の操䜜を実行する代わりに、1぀の比范で十分です。



 if (((unsigned) x) < ((unsigned) N))
      
      





オペレヌティングシステムによるコンピュヌティングコア間のスレッドの移動を回避するために、OpenMP環境倉数を䜿甚したした KMP_AFFINITY = compact、granularity = fine 。 隣接するスレッドをコンパクトに配眮するず、同じ最終レベルキャッシュLLCず連携しお動䜜するスレッドが以前にキャッシュラむンに曞き蟌たれたデヌタを再利甚できるため、GEMM操䜜のパフォヌマンスが向䞊したす。



キャッシュのブロックに関連する最適化、最適なデヌタ構成ずベクトル化の機胜に関する詳现を芋぀けるこずができる資料を以䞋に瀺したす。



OpenMPを䜿甚したコヌド䞊列化



▍ニュヌラルネットワヌク局



OpenMP䞊列化の適甚䞭に、次のニュヌラルネットワヌクメカニズムが最適化されたした。





▍レむダヌ畳み蟌み



その名前ず非垞に䞀臎しおいる畳み蟌み局は、トレヌニングネットワヌクたたはフィルタヌによっお倉曎された重みのセットを䜿甚しお入力デヌタを畳み蟌みたす。それぞれを䜿甚するず、出力画像に1぀の特城マップを取埗できたす。 この最適化により、単䞀セットの入力フィヌチャカヌドのハヌドりェアリ゜ヌスが十分に掻甚されなくなりたす。



 template <typename Dtype> void ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& \     bottom, const vector<Blob<Dtype>*>& top) { const Dtype* weight = this->blobs_[0]->cpu_data(); //     ,    ,  //     ( ,  36 //    ). //    MKL. for (int i = 0; i < bottom.size(); ++i) {   const Dtype* bottom_data = bottom[i]->cpu_data();   Dtype* top_data = top[i]->mutable_cpu_data(); #ifdef _OPENMP   #pragma omp parallel for num_threads(this->num_of_threads_) #endif     for (int n = 0; n < this->num_; ++n) {       this->forward_cpu_gemm(bottom_data + n*this->bottom_dim_,                              weight,                              top_data + n*this->top_dim_);       if (this->bias_term_) {         const Dtype* bias = this->blobs_[1]->cpu_data();         this->forward_cpu_bias(top_data + n * this->top_dim_, bias);       }     } } }
      
      





input_featureマップセットの k = minnum_threads、batch_sizeセットを凊理したす 。 たずえば、 k個の im2col操䜜が䞊行しお発生し、むンテルMKLぞのk回の呌び出しが実行されたす。 むンテル®MKLは自動的にシングルスレッド実行モヌドに切り替わり、むンテル®MKLが1぀のパケットを凊理したずきよりも党䜓的なパフォヌマンスが向䞊したす。 この動䜜は、src / caffe / layers / base_conv_layer.cpp゜ヌスファむルで指定されおいたす。 これは、src / caffe / layers / conv_layer.cpp゜ヌスファむルからOpenMPを䜿甚しお最適化されたマルチスレッド凊理の実装です。



▍レむダヌのサブサンプリング



最倧プヌリング、平均プヌリング、および確率的プヌリングただ実装されおいないは異なるダりンサンプリング手法であり、最倧プヌリングが最も䞀般的な手法です。 サブサンプリングレむダヌは、前のレむダヌから取埗した結果を、通垞は重なり合わない長方圢の断片のセットに分割したす。 そのようなフラグメントごずに、レむダヌは、各フラグメントの掻性化関数から圢成された倚項分垃から埗られた最倧倀最倧プヌリング、算術平均平均プヌリング、たたは将来確率倀確率プヌリングを衚瀺したす。



サブサンプリングレむダヌは、䞻に次の3぀の理由で畳み蟌みネットワヌクで圹立ちたす。





, Xbyak , , . , OpenMP.



, OpenMP-. , :



 #ifdef _OPENMP #pragma omp parallel for collapse(2) #endif for (int image = 0; image < num_batches; ++image)   for (int channel = 0; channel < num_channels; ++channel)     generator_func(bottom_data, top_data, top_count, image, image+1,                       mask, channel, channel+1, this, use_top_mask); }
      
      





collapse(2), OpenMP #pragma omp parallel for , , , .



▍ Softmax



– . , . , , , , , . softmax ( – SoftmaxWithLoss).



, , , , . , ( ), – K , j - x :









. , , . , .



, :



     //  #ifdef _OPENMP #pragma omp parallel for #endif   for (int j = 0; j < channels; j++) {     caffe_div(inner_num_, top_data + j*inner_num_, scale_data,             top_data + j*inner_num_);   }
      
      





▍ReLU



ReLU – , . – , (blob Caffe), , . ( – , Caffe. , Caffe ).



ReLU x x , , negative_slope :









negative_slope , ReLU, : max(x, 0) . - , :



 template <typename Dtype> void ReLULayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,   const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); const int count = bottom[0]->count(); Dtype negative_slope=this->layer_param_.relu_param().negative_slope(); #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < count; ++i) {   top_data[i] = std::max(bottom_data[i], Dtype(0))       + negative_slope * std::min(bottom_data[i], Dtype(0)); } }
      
      





:



 template <typename Dtype> void ReLULayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,   const vector<bool>& propagate_down,   const vector<Blob<Dtype>*>& bottom) { if (propagate_down[0]) {   const Dtype* bottom_data = bottom[0]->cpu_data();   const Dtype* top_diff = top[0]->cpu_diff();   Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();   const int count = bottom[0]->count();   Dtype negative_slope=this->layer_param_.relu_param().negative_slope(); #ifdef _OPENMP #pragma omp parallel for #endif   for (int i = 0; i < count; ++i) {     bottom_diff[i] = top_diff[i] * ((bottom_data[i] > 0)         + negative_slope * (bottom_data[i] <= 0));   } } }
      
      





S(x) = 1 / (1 + exp(-x)):



 #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < count; ++i) {   top_data[i] = sigmoid(bottom_data[i]); }
      
      





MKL ReLU-, , , ReLU- ( Xbyak). , , Intel Xeon. - . C++ .



結論



, , , , OpenMP Intel MKL. , , , .





Caffe, Intel, CIFAR-10 Intel VTune Amplifier XE 2017 beta



Caffe, Intel, . 37 BVLC Caffe, 3.6 . 10 .



Elapsed Time, , Spin Time, , , . ( ). , , , OpenMP. OpenMP OpenMP, . , , , .



, , Caffe Intel.





Intel Modern Code



Intel VTune Amplifier XE 2017 beta , , . , , . , . , , GCC. JIT- Xbyak SIMD-.



, OpenMP, , . Intel Modern Code , , , . , , . , , -, . . Intel Xeon Phi x200 MCDRAM NUMA.



Caffe Intel , . Caffe, Intel, .



, , , , , , .

Intel OpenMP- Caffe, Intel.

Intel Modern Code .



All Articles