目次

はじめに

注意事項
表記関係について

第一章 プログラムできるハードウェア

基礎知識:FPGAとは
ソフトウェアのFPGA化にあたって
FPGA開発言語(HDL:Hardware Description Language)
FPGAの処理構成
FPGAの開発フロー

第二章 開発環境の整備

SDSoCとは
開発環境(Linux環境)
SDSoCのダウンロード
インストール
ライセンスの取得
起動とライセンスの設定
評価ボード
ZedBoard

第三章 ハードウェア・プログラミング (スタートアップ編)

プロジェクトの作成
プロジェクト
ソースコードの作成
コンパイル
実機で動作確認
FPGA化する関数の指定

第四章 機械学習ソフトウェア

アルゴリズムを確立する
ソースコード
関数の構成
ソフトウェアの動作確認

第五章ハードウェア・プログラミング(組み込み編)

ケース0:SDSoCに適用
ケース1:関数のFPGA化
ケース2:SDSoCのpragmaで転送方式の指定
ケース3:FPGA化する階層を1つ上げる
ケース4:2つの関数をFPGA化
ケース5:上位関数CNNLayerを対象

第六章 ハードウェア・プログラミング(チューニング編)

アルゴリズムの把握
FPGA化関数のトレース
データアクセスの修正
上位関数のトレース
メモリアクセス
ソースコードのリファクタリング
メモリアクセスとリファクタリング例
生成される回路規模
HLSプラグマの適用
エミュレータ

あとがき

著者紹介

はじめに

 ソフトウェアからFPGAやASICなどのハードウェアを開発する手法は古くからあり、ハードウェア業界では一般的に高位合成と呼ばれます。

 近年、AIやディープラーニングの勉強会やFPGA関連のコミュニティベースでの勉強会などで、ソフトウェアから高位合成でもFPGAを開発する発表などが多くなってきました。高位合成が目立つようになってきたのは高位合成ツール本体の価格が下がってきていること、また、本書のようなC言語からの高位合成だけではなく、Java・Python・rubyといった言語からも高位合成できるツールなども登場し、FPGAを使うためにわざわざ専用の言語を使う必要性が無くなりつつあるところにあります。

 ソフトウェア・エンジニアの中には、「ハードウェア」というだけで毛嫌いされる方もいますが、このように様々がツールが登場したおかげで高位合成自体の敷居も徐々に下がり、その出番が多くなってくることでしょう。これからはますます、FPGAを扱えるソフトウェア・エンジニアが増えてくると考えられます。

 筆者は普段、FPGA側のハードウェア・エンジニアとして観点からFPGA関連の記事や同人誌などを執筆しています。本書では逆に、ソフトウェア・エンジニアの目線からFPGAの特性を見る、という観点で機械学習の一つであるCNNをFPGAに適用していくチュートリアル形式で高位合成を行いました。

 本書を出版するにあたってご尽力して頂いたインプレスR&D山城様に厚くお礼を申し上げつつ、本書を読んで頂いた皆様にはソフトウェアでのFPGA開発の可能性を感じ取って、FPGA開発を活用したソフトウェア開発にチャレンジして頂ければ幸いです。

注意事項

 この本に掲載されているURL、商品価格、入手先などは2017年9月時点のものです。

表記関係について

 本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。



第一章 プログラムできるハードウェア

 近年、FPGAを使用したハードウェア・アクセラレーションの中でもソフトウェアと連携したハードウェア・アクセラレーションが注目されています。Microsoft1百度(バイドゥ)2などの検索エンジンで使用されたり、画像認識などの機械学習や深層学習3などに使用されるケースが多くなってきました。また、開発ツールや評価ボードといったハードウェアの入手もしやすくなり、気軽にFPGAを使用したプログラムのハードウェア・アクセラレーションを行うことが可能になってきました。

 さて、一昔前のFPGAは、カスタム・インターフェースの処理、ネットワークや映像・放送送信の通信処理や画像処理などで多く使用されてきました。そのような現場ではFPGAのハードウェア開発とソフトウェア開発を切り離して行うことが多く、FPGA開発においてはVerilog HDLやVHDLなどのハードウェア記述言語を使用して開発するケースが多くありました。現在でもそのような分野のFPGA開発ではハードウェア言語を用いた開発が主流となっています。

 では、FPGAを開発・利用するためにはハードウェア言語を使用しなければいけないかというと、必ずしもそうではありません。現在ではC言語などで開発を行う「高位合成」という手法でもFPGAを開発することが可能になっており、ソフトウェア・エンジニアでもFPGAを容易に扱うことが可能になってきました。

 本書ではC言語で開発された機械学習の1つであるCNN(Convolutional Neural Network:畳み込みニューラルネットワーク)のアプリケーションを題材に、Xilinx社のSDSoCを用いてFPGAでハードウェア・アクセラレーションを実現する方法についての開発例を、実例を交えて解説します。

基礎知識:FPGAとは

 FPGAとはField Programmable Gate Arrayの略で、再構成可能なハードウェア4です。FPGAの中身は回路を構成するためのロジック、DSP、RAMや専用のハードウェア・マクロなどがあり、これらを組み合わせて専用の回路を作ります。現在のFPGA業界はXilinx社とIntel社(旧Altera社。2015年にIntel社が買収)の二社のデバイスが市場の大半を占めています。

図1-1:FPGAの構成

 例えば、「ビデオカメラの映像を白黒変換してモニターに映す」というシステムを作る場合、図1-2のようにFPGAで画像フィルター回路を作成し、システムの一部又は単独のシステムとして使用されます。

図1-2:白黒画像フィルターのシステム構成例

FPGAの得意分野

 FPGAを使用してハードウェア・プログラミングを行うためには、FPGAが得意とするところ、そして、FPGAをどのように使用するとメリットが発生するのかを理解してプログラミングする必要があります。

独自回路の設計

 FPGAは自由に回路を構成し設計できることから、何らかの目的専用の処理を行う独自回路を開発することができます。例えば、「独自開発の汎用的ではない通信方式」や「特殊な映像効果を与える画像処理」などをFPGA上で独自に回路を開発して実現することが可能です。この時「汎用的な処理を行う回路」とは、CPUの周辺ペリフェラル(UARTやSATA、PCIeなどのインターフェース)などを指します。多くのコンピュータはこれら汎用の回路をハードウェア・コントローラ(ハードウェア・マクロ)として実装しています。そして、汎用のハードウェア・コントローラが実現できないことをFPGAでは実現可能です。

並列処理

 FPGAでは処理を並列して行うことができます。CPUではプログラミングされた命令を逐次実行していきますが、FPGAでは同時にいくつでも並列して処理する回路を設計することができます。

 例えば、リスト1-1のようにforループ文で100回の乗算をするようなソースコードの場合、一般的にCPUでは100回の乗算を繰り返し行いますが、FPGAではリスト1-2のように100個の乗算器を並べて配置し一度の時間軸に並列に演算することも可能です。

リスト1-1:forループでの演算

for( I = 0; i < 100; ++i){
 z[i] = x[i] * y[i];
}

リスト1-2:並列に並べられた演算
z[0] = x[0] * y[0];
z[1] = x[1] * y[1];
z[2] = x[2] * y[2];
...
z[98] = x[98] * y[98];
z[99] = x[99] * y[99];

CPUとFPGAの違い

 FPGAを用いたハードウェア・プログラミングを行うためにCPUとFPGAの処理方法の違いを理解しておきましょう。

CPUでのソフトウェア処理

 CPUでは、ソフトウェアの実行をプログラムで記述されている順番に、CPUコアに用意されている命令処理回路で処理を行います。図1-3のように、プログラミングされた命令はメモリから読み出され、デコード、実行、メモリに書き戻す一連の動作を繰り返します。

図1-3:CPUの処理

FPGAでのハードウェア処理

 一方FPGAは、内蔵されたロジック、乗算器、RAMなどを組み合わせて専用の回路を構成、処理の順番にそって各専用回路を構成し、接続して動作させます。各専用回路は同じ時間軸で動作し、入力される信号がくるとすぐに動作します。

 例えば、図1-4のようにFPGA上で入力信号を処理する回路を2つ作成するとこの2つの回路が同時(並列)に処理することが可能です。

図1-4:FPGAの処理

 また、CPUでは図1-5のように乗算命令を実行するときは除算や加算、減算回路は使用しないのに動作させたままになります。一方、FPGAは使用しない回路を実装する必要がないので、CPUコアのように無駄な回路を動作させておく必要が無くなります。無駄な回路を動作させないということはそれだけ電力を消費しないということにつながります。つながります。

図1-5:CPUでの演算処理


処理性能

 CPUとFPGAで同じ処理を実現した場合にどちらの方が処理性能が良いかというのはこれについては一概に比べることができません。次のようにCPUとFPGAの動作周波数が大きく違うからです。

 ・一般的に汎用的なCPUは数100MHz〜2GHz程度で動作します

 ・FPGAで設計した回路は一般的に数10MHz〜数100MHzで動作します

 FPGAとCPU処理の違いは既に述べているようにFPGAが並列処理、CPUが逐次処理である点にあり、同じ動作周波数であれば、並列処理が行えるFPGAのほうが処理能力(スループット)が高くなります。例えば、リスト1-3のような演算式の処理をもとにCPUとFPGAでの処理の違いを見てみましょう。

リスト1−3:演算式

y = ( a * b ) + ( c * d ) + ( e * f ) + ( g * h )

CPUでの処理

 CPUの処理はリスト1-4のようにCPUコアにあるレジスタ(リスト1-4ではr0〜r2がCPUのレジスタ)にメモリから読み込んだ値を代入して演算回路で逐次実行します。

リスト1-4:CPUでの実行例

  r0 = a
  r1 = b
  r2 = r0 * r1
  r0 = c
  r1 = d
  r0 = r0 * r1
  r2 = r2 + r1
  r0 = e
  r1 = f
  r0 = r0 * r1
  r2 = r2 + r1
  r0 = g
  r1 = h
  r0 = r0 * r1
  r2 = r2 + r1
  y = r2

FPGAでの処理

 FPGAでは図1-6のような回路構成にすると一度に演算を完了させることが可能です。

図1-6:FPGAで演算の一括処理

 また図1-7のように、演算回路毎に分割し、クロックで同期させる回路を構成することも可能です。この場合は、乗算器及び加算器は同じ時間軸で処理され、結果はそれぞれの演算器を順番に伝達されます。例えば、演算回路の時間軸をクロックで表現した場合は3クロック後に結果がyに出力されます。

図1-7:演算処理ごとにブロックを分けた場合

 FPGAに限らず、処理回路が多いほど結果が出力されるまでに時間がかかるため、一概にどの回路構成が良いかはシステムの設計思想で変わってきます。FPGAでの開発では絶えずこのような並列性の処理を考えながら論理設計を行っていきます。

 しかし、リストのような回路を実際にFPGAで設計した場合、最高動作周波数は100MHz(=1つの演算回路の伝達に10ns)程度になります。例えば、1GHz(=1命令を1nsで実行)で動作するCPUと比較してみましょう。

 CPUは16回の命令を実行するので16nsで演算が完了します。一方、FPGAは3回の信号伝達で演算が完了するので、30nsの時間が必要になります。もし、FPGAの動作周波数が1GHzであれば、当然、FPGAの方が処理が早く完了します。

 このように、局所的に見ると命令の実行数が多くてもCPUのほうが処理性能が高いと言えます。

図1-8:CPUの処理時間
図1-9:FPGAでの処理時間

パイプライン化

 よくFPGAのメリットの1つとして取り上げられるパイプラインがあります。パイプラインはCPUとFPGAで意味合いが違います。

CPUのパイプライン

 すでに同じようなことを述べていますがCPUのパイプラインは図1-10のように「命令実行のパイプライン」です。

図1-10:CPUのパイプライン

FPGAのパイプライン

 FPGAのパイプラインは図1-11のように「処理のパイプライン」を構成することが可能です。

図1-11:FPGAのパイプライン

 では、FPGAのパイプラインではどのようなメリットがあるのでしょうか。リスト1-1の演算式のyを算出するまでの時間に注目してみましょう。CPUの動作周波数が1GHz、FPGAの動作周波数が100MHzとします。この環境においてCPUでリスト 1-2を実行、FPGAでリスト1-4を動作させたとします。1回あたりの演算時間はCPUで16ns、FPGAで30nsと前項で述べました。この点だけを捉えればCPUの方が演算速度が速いことになります。

 しかし、図1-12のようにこの演算について10,000回ループ演算を行った場合、CPUでは16ns×10,000回=約160μs、FPGAでは10ns×10,000回=100μsとなりFPGAの方が処理速度が速くなります。

 このように、FPGAでは処理のパイプラインによってCPUよりも速く演算できるメリットが生まれます。

図1-12:演算を10,000回実行するときの処理比較

 つまり、FPGAを使ったハードウェア・プログラミングで、CPU処理よりも満足な処理性能を得るためには、いかに演算を含めた処理がパイプラインにできるかが非常に大きな要素になります。

割り込みによる実行の中断

 CPUでは様々な機能をリアルタイムに制御するために、割り込み処理が使用されます。割り込みの度に現在実行している処理を中断して処理を行います。

 FPGAでは並列処理が可能なため、割り込みの必要がないため割り込みによる遅延が発生しません。このことからリアルタイム処理に向いています。

可変出来るbit長

 CPUは32bit CPU、64bit CPUといったぐあいに基本的にレジスタの長さが決まっています。32bit CPUで64bit同士の演算を行う場合は、CPUのレジスタ長に合わせて各桁を分解して演算する必要があり、1命令で演算を完了することができません。

 例えば、32bit CPUで64bit変数aと64bit変数bの乗算を行う場合は、次のように式を分解して計算を行うことになります。


 (( aの上位32bit * 2^32 ) + aの下位32bit ) * (( bの上位32bit * 2^32 ) + bの下位32bit )


 FPGAでは64bitでも1,024bitでも演算回路を用意して処理することが可能です。32bit CPUで4bit同士の演算を行う場合は32bitのレジスタを使用しなければいけないため、28bitの無駄なレジスタも使用しなければなりません。FPGAの場合は4bitの演算回路を用意すれば良いので、無駄な回路を作成する必要がありません。CPUでは使用していないbitでも電力が消費されますが、不要なbitを削減できればそれだけ消費電力を下げることが可能です。

 このように同じ演算でもFPGAでは不要な回路が無くなり消費電力を下がります。消費電力の低下もFPGAのもうひとつのメリットです。

ソフトウェアのFPGA化にあたって

 ソフトウェアをFPGA化するうえで、無闇にFPGA化を行っても性能を向上するどころか何のメリットも生まれません。CPUとFPGAの得意分野は全く違う方向を向いているので、ソフトウェアをFPGA化するにはここまでに述べたCPUとFPGAの違いをよく理解し、CPUで実行すべきなのか、それともFPGAで実行すれば何らかのメリットが得られるのかを判断する必要があります。

 CPUは命令を逐次処理することを一次元と捉えれば、FPGAは図1-13のように三次元的な要素であると思い浮かべてください。ハードウェア・プログラミングにおいては、処理をしている部分が一次元で済む話なのか、三次元に展開したほうにメリットがあるのかを考えながらソフトウェアを構築するようにしましょう。

図1-13:CPUとFPGAの処理イメージ

 また、ソフトウェアの処理をFPGAに展開して処理性能を向上させるということは、処理をパイプライン化してレイテンシ(処理の遅延時間)を短くして、処理の並列化によってスループット(単位時間あたりの処理能力)を向上させる点も意識したプログラミングが必要です。

図1-14:スループットとレイテンシ
試し読みはここまでです。
この続きは、製品版でお楽しみください。