Kotlinで作る自由でラクなMOVERIO BT-200開発環境 2ヶ月目

2015年4月30日木曜日

Engadget・エプソン主催のMOVERIO体験会へ参加し、MOVERIO(BT-200AV)を6ヶ月間の無料モニターとして借り受けました。
本記事は、無料モニター2ヶ月目の記事です。
前回: 新MOVERIOは実用端末たりうるか。BT-200AVを借りて試した話
先月は、基本的に一般利用の視点でみていきました。ハードウェアとソフトウェア両面について雑多なメモを書き、特にAmazonのアプリストアを突っ込めば結構多くのシーンでアプリ不足はカバーできるのでまあそれはそれで、という話を書きました。
概況を把握したところで、今月はアプリ開発のための下準備をしました。

Effective C++読書メモ #32

Item 32: Make sure public inheritance models "is-a."
前回: Effective C++読書メモ #31
前回はコンパイル時の依存関係を減らすためにHandlerパターンやInterfaceパターンを使うこともできて、これらによるオーバーヘッドを避けたければprodビルド時にこの部分を差し替えられるような方法をとるのが良いよというつらそうな話だった。
今回はpublic継承の話。「「public継承はis-aだよ」」
えらく寓話的に、とにかくしつこく頭へ刷り込むように書いてある。
他のトピックはこの周辺を補強するもの。
  • ある振る舞いを持たない継承関係に関して、実行時エラーを出すようにするよりはコンパイル時にエラーを見つけられるようにしたほうが良いよという話
  • public継承をすると親の挙動は常時維持されるかというとそうではないよねという議論
  • rectangleとsquareの実装については分かりやすかった
    • 親のクラスで定義されているフィールドの一部を子の側でいじるなど、親の想定している状態に対して手を加えた場合に挙動が変わっても仕方ないねという話で、それは仕方ない
他の策としてhas-ais-implemented-in-terms-ofが挙げられている。これらはもう少し後のチャプターで出てくるのでその時に。

Effective C++読書メモ #31

Item 31: Minimize compilation dependencies between files
前回: Effective C++読書メモ #30
前回はinlineの使い方という話だった。今回はコンパイル時の依存関係をなるべく減らせという話。
再コンパイルを避けるためになんでもかんでもforward declarationへ逃がすのはむり。コンパイル時にオブジェクトの大きさを把握しておく必要があるし、テンプレート絡みだと正確な定義がどういうものか前方宣言だけではわからないから。
インタフェース定義のみを含んだクラスを作り、それにshared_ptrで実装クラスの実体を紐付けるpimplイディオムというのが紹介されてる。declarationとdefinitionでヘッダファイルを分けて両方メンテしろというのは結構厳しいなぁ。Clangとかコンパイル高速なやつを使えばそういう人間へ優しくない方法はそこそこ避けられる気がする。しかしこの用途のためにあるらしいiosfwd(iostreamのforward declarationをまとめたファイル)を知ることができたのはプラス。
この節でC++に純粋なinterfaceは構文として存在しないよというのを読めたのも結構プラス。
ところどころよく分からん(virtual ctorとかなんぞという)ので、この節はそのうち戻ってきてちゃんと読みなおす。節の結論としては、HandleクラスやInterfaceクラスは開発中のビルド時間削減に使って、最終版ビルド時にはこれらを外すようにするのが良いという話だった。
次からはC++におけるOOPの話。

Effective C++読書メモ #30

Item 30: Understanding the ins and outs of inlining.

これまでメモ無しで読んできていたのを他の本と同様にメモ残していくようにしたので今回から。Effective Objective-Cのメモとスタイルを揃えて通番途中からスタートしてみる。

インライン化の恩恵は関数っぽく扱えつつ関数呼び出しのオーバーヘッドがないというだけではない。コンパイラによるコンテキスト固有の最適化を追加でおこなえるかもしれない。逆に、コードサイズが増えてキャッシュミスしやすくなるかもしれない。インライン関数がかなり小さなものだったら、関数へコンパイルされるよりもコードが小さくなるかもしれない(スタックのpush/popとか無いのだし当然ではある)。

暗黙的なインライン関数の書き方があるの知らなかった。constで直値を返すアクセッサメソッドは勝手にinline扱いになるということなのかな。

テンプレートを考えなしにインライン化宣言するなという話もあったけれど、ちゃんと理解するにはC++力が足りなかった。そのうち戻ってこよう。

インライン化はコンパイラによって無視されうるという話。これ知らなかった。ループを含んだり再帰するようなものは無視する(そりゃそうか。これを安全にインライン化すると結局関数へ切り分けるのと同じかそれ以上に複雑なコード生成となりそう)。あと、virtualキーワードのついたもの(つまり実行時までどれが選択されるか分からないもの)もinlineできねーよとして無視される。言われてみると当然だった。

インライン関数のポインタを用意した場合などには、それに該当する実体が作成される。こうして整合性を取る(実体も別途用意されるの意かな)。

なんでもかんでもインライン化していいわけじゃないという話が続く。例としてctor/dtorが挙げられている。C++の仕様が求めることをコンパイラが実装した結果なにが起こるかという話。仮に空っぽのコンストラクタでも、フィールド初期化などはしてる。そしてその中で例外が起こったらすべて無かったことにしてくれる。これは裏側で例外処理時のコードを大量に生成してる。

ライブラリ構築時にはインライン化するか否かちゃんと考える必要がある。ライブラリの中身をインライン化してしまうと、ユーザの手元にあるそのコードをバイナリ差分として更新する手立てがない。焼きこまれてるんだから、当該コードを更新するためには再コンパイルが必要。インライン化されてなければ別バイナリをリンクし直すだけでok。この視点は無かったので役立つ。

デバッガの邪魔にもなる。これも気付いてなかった。言われると当然で、そもそも関数じゃないんだから単純にコールスタック追えない。まあプログラムカウンタはちゃんと分かる場所にあるはずなのでそれぐらい頑張ってほしいという気持ちではある。

まとめとして、明らかにインライン化すべき場所以外では使うなということだった。ここの処理コストを気にするほど全体は効率的に動かないじゃろというのが主なイメージ。

面白かった。

Essential C# 5.0読書メモ #3

前回: Essential C# 5.0読書メモ #2
前回はChapter 2で値型と参照型、そして配列の話。終わりのほうは特にメモ書くことなかったのでスルーして、今回は続きのChapter 3。
Chapter 3は演算子と制御フローの章。
ここもほぼ読むところはないのでメモ箇所のみ。

浮動小数点演算について

+Infinity-Infinityがあること
IEEE 754準拠の浮動小数点演算では+0と-0の区別がある。単純に0.0と-0.0は区別して処理してくれるということで、きっと便利なシーンがある(自分の手元ではさほどなさそう)。

インクリメント/デクリメントについて

C++ではfoo(x++, x++);とした際の評価順がコンパイラ依存となっているが、C#では常に左から順に評価されるという話が書かれていた。あまり複雑なインクリメント配置はしたくないけれど、覚えておくと便利そうなやつ。
スレッドセーフでlockを利用しないインクリメント/デクリメント方法としてSystem.Threading.Interlockedクラス内にIncrement()Decrement()という両メソッドが生えているとのこと。
これらはプロセッサが持つ機能を使ってスレッドセーフに高速なインクリメント/デクリメント処理をおこなってくれると書かれていた。x86だとinc/dec命令とか使ってくれるのだろうか

コードブロック、スコープ、宣言空間

コードブロックとスコープは正確には違うよという話。unqualified nameで参照できる範囲がスコープで、ローカル変数のスコープはそれを囲むコードブロック。
そしてスコープと宣言空間も違う。スコープは、ある名前が何を指すかを解決するためのもの。宣言空間は、2つのものが同一の名前を持ってはいけない範囲のこと。
コードブロックはスコープの定義と共に宣言空間の定義もおこなう。

条件付き演算子

? : なやつ。C#で唯一の三項演算子だから三項演算子と呼ばれることもあるけれど、基本的には条件付き演算子と呼んだほうが良い旨が書かれていた。

null合体演算子

これ自体はそこそこ使うけれど、Coalescingという単語が特殊でよく覚えられないと気付いたのでメモ。

foreachループ

ループ本体がループ変数を利用するラムダ式か匿名メソッドを含む場合にループ変数の挙動がC# 5より前と5以降で異なるという話(詳しくはChapter 12らしい)があったのでメモっておく。

switch文

  • switchセクションからの脱出にcontinueを使うのは挙動把握が紛らわしくなるのでやめれとあった(そもそもそのパターンで使おうと思ったことがないけれど)
  • fall-throughをどうしても実現したければgotoを使えとあってファァとなった
    • goto default;以外、つまりラベル指定をおこないたければgoto case constant;とするように、とあって用途の特殊感が出てた
    • まあこうやって用途を制限してgotoにまつわる厄介な問題を回避するように言語設計されてるけど、やっぱりコードの流れを追いづらくなるのでgotoは避けようね、で終わっていた
  • defaultセクションを末尾に置く必要は特にないと書かれていて、そういえばそうかと思った

プリプロセッサ用のディレクティブ

#lineは馴染みがなかった。SourceMapのようなことができる(#warningで警告を発生させる際に、当該警告箇所ではなく別の場所が原因で問題が発生したことをコンパイラへレポートするもの)。
ライブラリを作っていると便利なシーンがきっとある感じがした。
結構長い章だったけれどこれで終了。次のChapter 4はメソッドとパラメータ。

Essential C# 5.0読書メモ #2

前回: Essential C# 5.0読書メモ #1
Chapter 2のちょうど真ん中あたりまで、データ型について読んだところだった。今回はその続きで値型と参照型のあたり。

値型と参照型の話

粛々と進むので粛々と読む。
途中で出てきたキャスト時の値あふれを例外として処理するための構文(リスト1)は知らなかった。セットでuncheckedも。
リスト1 checked構文の例
checked {
  var n = int.MAX;
  n = n + 1;
}

配列の話

Jagged Arrayの話がこんなにちゃんと出てくるの初めてだ…(それぐらい使ってない)。
さらっと終わるかと思うと結構続く。
BinarySearch()というメソッドが配列に生えているのを知らなかった。事前にソートしておかないとまともに結果を返してくれないよ、というのはそらそうだ。

あまりメモ量は無いけれど、Chapter 2が終わったのでここまでで今回は終了としておく。

Essential C# 5.0読書メモ #1

Essential C# 5.0はよいものだ、ということで読んだメモを残していく。
#1だけど途中(chapter 2)から。chapter 1は特にメモを取ることもないかなーと思ってさらさら読んだため。
今回はデータ型について。C#では数値型の種類が充実してるという話から、浮動小数点型やdecimal型の話まで展開していく。

string

Stringは単純にSystem.Stringの省略というのは見落としてた。言われてみればそりゃそうだ。

decimal

decimal型について、これまで全然使ったことがなかったので知らなかったことや誤解してたことがいっぱいあった。
JavaのBigIntegerのようなもので十進格納の多倍長型だと思ってたけれど、128-bit固定のものだった。値の範囲が±N * 10^k (N: 96-bitの正の整数、-28 <= k <= 0)ということでああなるほど、となった。
軽く計算した感じ、96-bitだと28.896桁ぐらいが有効、ということで有効桁数が28-29となっているのも納得いった。
decimal型のリテラル・サフィックスがMまたはmというのも全然知らなかった。ひょっとするとこれまでにどこかで見てるのかもしれないけど、脳で拾ってなかったっぽい。
リテラル・サフィックスは基本的に大文字で書くようにとある(これ自体はlongのlが1と紛らわしいから+他のも揃える意かな)けれど、まあそうならなかった環境もあるよなぁ(Unityとか)。
string.FormatでのR(またはr)フォーマット指定、知らなかった。Parse()すれば元の数値へと戻せるようなラウンディングをしてくれるのは便利なのかもしれない(単純にこれまで使ったことがない)。

char

charの実体は8-bit(byte)だと思い込んでたけれど16-bit(ushort)だと知った。これも完全に意識してなかったやつだ。運の良い日本語文字はcharに収まるということか…。試してみないと。
リスト1のコードをコンパイルしてみると
リスト1 サロゲートペアを含む文字をcharへ突っ込んでみる
using System;

class A {
  public static void Main() {
    char c1 = 'ヴ';
    char c2 = '𠮟';
    System.Console.WriteLine("{0}", c2);
    return;
  }
}
リスト2のようにエラーとなる。
リスト2 サロゲートペアを含む文字をcharで表現するのはコンパイルエラー
mcs a.cs
a.cs(6,13): error CS1012: Too many characters in character literal
Compilation failed: 1 error(s), 0 warnings
なるほど。日本語を扱う時にはstringばかり使うので全然気付かなかった。

var

右辺値の型が明確である場合に暗黙の型指定を使うように、というポリシーが書かれてた。昨今は特に考えず暗黙の型指定をしてるけど、もう少しは意識してみようかな。
値型と参照型のところまで進みかけたけど、まだこのチャプターの先が長いことに気付いてやめた。

Unreal Engine 4 ビデオチュートリアル記 #3

前回: Unreal Engine 4 ビデオチュートリアル記 #2
前回はシーンレンダリング時の色合いを変化させる(Color Grading)方法とスローモーション効果についてだった。
今回はその続き。

ジャンプ台の作り方

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=6admWItFIsE

3分弱。
ジャンプ台のメッシュをCylinderで適当に作って、コリジョンタイプをデフォルトのBlockAllDynamicからOverlapAllDynamicへ変更することで自キャラが踏めるようにする。
あとはActor Begin Overlapのイベントを受け、対象をThird Person Characterへキャストできたらその対象に対してLaunch Characterで吹っ飛ばすというもの。
とても分かりやすい流れだった。
しかし、UE4自体が日本語UIになっているとBPの補完候補絞り込み部分で非常に不便(castなどがカタカナでないと出なくなる)なので英語UIにしようと思った。

ホバーコンポーネントの作り方

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=5kltaGld6fQ

15分弱。長い。
プリミティブに作用して対象を空間へ浮かせておけるようにするコンポーネントを作るという回。
Line Trace by Channelを使って浮遊表現をする。
Promote To Variable便利。適当な値を指定してBPを作り、それを変数化するとデフォルト値がさきに指定したものになるのでよく使うテクニック、という話をしていた。
内部で変数定義したものを外部へと公開するのもとても簡単。
Line Trace by Channelで対象オブジェクトが何かにぶつかった場合の処理を作っていく部分が少々複雑だった。Break Hit Resultでヒットテスト情報を分解し、World Locationとの差分の長さを適当なファクタで割り、結果を適当な範囲へと正規化してImpact Normalに掛けたものをAdd Forceでオブジェクトへ反映する、というところまでがメイン。
これだけだと地面すれすれで跳ねる度に反発が大きくなっていくのでLinear DampingAngular Dampingを設定して制限する、というのが仕上げ。
シミュレーション実行中にプロパティを変更した際、kを叩くと値を保存できるというのが便利そうだった。

図1 ホバリングするコンポーネントのBP

2つめが長かったので今回はここまで。次回で最初のシリーズが終わるはず。

Unreal Engine 4 ビデオチュートリアル記 #2

前回: Unreal Engine 4 ビデオチュートリアル記 #1
前回はメッシュ破壊、カメラ揺らし、タイマー利用の3点をなぞった。
今回はその続き。

Color Gradingを使う

シーンをレンダリングする際の色合いをいじるもの。
https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=oBzHB-VRCS0

4分弱。
オンラインマニュアルの中でポストプロセスエフェクト部分にあるColor Gradingまで遷移してね、から始まるのが新鮮だった。
このページには「Color GradingというのはTone Mapping機能と、それに加えてColor Correctionを指します」とある。
適当なシーンのスクショを撮り、それをPhotoshop上でいじって作った色のルックアップテーブルで簡単にColor Gradingを実現するというもの(図1、図2)。

図1 Color Gradingの適用前 

図2 Color Gradingの適用後

なるほど夢の広がるやつだ。
しかし「Photoshopでこれやります」と唐突にくるのが不意打ちだったので、全然実時間で追いかけられなかった。

スローモーション効果をかける

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=oX_uSjO270g

4分弱。
まず、エディタ内にゲーム速度をいじるためのslomoコマンドが用意されてるのに驚いた。加速方向にもいじれてえらい。
Build StringでPrefixの最後にスペースを入れてなくてコマンドが効かない、というミスをした。適当にスペース補ってくれるとかなかった(まあなくて良さそうだった)。
完全に写経。Event Tickで毎フレーム処理する必要あるのかなーと思っていたら、自キャラの動作速度にあわせてゲームスピードを変えるというものだったので必要だった。
Vector Lengthでのベクター長取得とMap Rangeによる正規化というパターンは割とよくありそう。

Unreal Engine 4 ビデオチュートリアル記 #1

https://wiki.unrealengine.com/Videos

UE4は表現の幅が広い分、APIの探し方というか掘り方というか、そういうものが身についていないと何をするにも困る。ライトに扱えるものをいろいろ触っていくことで、「こういう仕組みが欲しければこの辺を掘れば良さそう」というのが分かっていくはず。
やはりチュートリアルのビデオを観ながら進めていくのがよかろうということで、観ながらやっていく。
まずはBasics(Blueprint Jump Starts)からいくつかやる。Basicsでは手軽にできて効果の高い手法をいろいろ紹介してる。
20本あるけれどいきなり全部はやらない。
なるべく実時間で追いかけたいけど、きっと慣れないうちはダメなのでその時は諦めてじっくり一時停止しつつ観る。BPのパラメータはパラメータ名へのマウスオーバーで詳細を表示してくれるものが多いので、見ればなんとかなるはず。

メッシュを破壊できるようにする

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=-gGiEmYj4oE

2分半とだいぶ短い。
途中でミスしなければ実時間でいける感じ。
元々用意されてるスタティックメッシュをいじって破壊できるようにする。
日本語化された環境では「被破壊性メッシュを作成」というメニューになってる。
ダメージを受けて破壊されるようにしてるんだけど、なかなか楽にできるようになってて面白い。そして、物理シミュレーションを有効化して仕上げというのがまた面白かった。

カメラを揺らす

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=1nMKHwsXSCc

3分半と結構短いけれど得られる効果が大きめなやつ。
CameraShakeクラスをもとに自前のパラメータを設定したカメラシェイク用のBPを作り、キャラクター側のBPチェーンへとPlay World Camera Shakeを追加して、その際のパラメータとして与えればokという。
これのパラメータはEpicenterがワールド空間でのエフェクト位置、そしてそれに対してInner RadiusからOuter Radiusまでの間にあるカメラが影響を受ける、ということでOuter Radiusをそこそこの大きさにしないと効かない(最初にやった時に桁一つ少なく指定してて、なんかシェイク効かないなーと思ってた)。

タイマーをつくる

versatile*1ノードと書かれてるタイマー。
https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gYeJX3xX44yzOb7_kTS7FPM&video=BeztKC4cO18

ちょうど3分ぐらい。画面上にポイントライトを作って、その色を一定時間間隔でランダムに変えるという例。
途中、ディスプレイの解像度が低すぎて画面右側のメニューがブルって見えてたけど、メニューを引っ張りだしてみるとブループリント/スクリプトを追加だった。
カスタムイベントを作成して、その名前をSet TimerFunction Nameに書き込むのは若干イマイチ感もあるけど、まあ分かりやすいのかもしらん。
[*1] 多才なとかそういう

ソフトウェア開発者もやっぱり気になるFPGA( #CodeLunch フォローアップ)

2015年4月28日火曜日

先日、CodeLunchというpodcastの収録へ行ってきました。

本職はスマフォアプリをC++で書いてる(書けるとは言っていない)とかそのへんなのですが、ハードの話をしようということでFPGAの話をしてきました。

Beatroboの竹井さんに随所で助けてもらいつつ、どうにかこうにか喋れた気がしますが、元々専門ではないエリアなので間違ってること喋ってるかも、という不安もありつつでした。

そういうわけで収録後に周辺情報を補足する資料を書こうと思って書いたのがこれです。

podcastはこちらです→ http://codelunch.fm/11/

なんでFPGAが注目されてるの?という話

Field Programmable Gate Array

どういうところで注目されてる?

1: 金融取引

http://www.hpcwire.com/2011/07/13/jp_morgan_buys_into_fpga_supercomputing/な話

金融取引でスピードは大事という話

  • podcastでは実際の想定利用シーンとしてアービトラージ(裁定取引)の話をしてる
  • 価格情報が届いた瞬間に発注してしまう
    • 補足: FPGAでの完全自動トレードは比較的新しい領域
  • 補足: メモリアクセスが頻繁に発生するとやはり遅いので、いかにこれを避けられる用途に絞るかというところにはなるはず

CPUに届く前にやろう

  • 補足: どちらかというとCPUに対して予め処理しやすい形式へと速やかに変換して値を渡すような部分がメイン(前出)ということで、話したのは少々飛ばしすぎたかもしれない

早さ大事という話

価格情報配信ってどれぐらい安定してる?

  • 補足: 改めて調べると、これは証券会社によって差が生じたことに対するペナルティだった
    • 純粋な価格情報遅延によるペナルティを受けたことはないぽい?調べきれなかった

金融関係のアルゴリズムってそんなに複雑じゃない?という疑問

補足: フラッシュトレード絡みだとフラッシュ・クラッシュ

Flash Crashについては別途ちゃんと読もう

2. FPGAで機械学習

MSのBing(補足: 2014年末時点では本番環境へ投入されていなかったけれど、そろそろ?)

ページランクみたいなやつに使い始めた

  • http://qiita.com/kazunori279/items/6f517648e8a408254a50
    • 例によってかずのりさん
    • 安定のかずのりさん
      • 補足: しっかりまとまってたので読み返そう
  • ランク付けをFPGAで
    • サーバ台数を半分ぐらいに減らせたよ
    • ランキングアルゴリズムは普遍的だから?→スパム対策などでよく更新されるということなのでは
      • 完全にハード化すると数ヶ月ごとにハードを捨てないといけなくなって辛い
      • だからFPGAなんじゃないかな(推測)

ほかの用途

  • 画像処理。最近は展示会などでも車載用が押されてる
  • カメラの中の画像処理にFPGAを使うとかもあった
  • 画像のフィルタリングに使われる
  • FPGAだと作り付けの回路よりも書き換えの手間が発生する
  • カメラの中身に、とか

FPGAってどうやって焼く?の

  • コンフィグROMから読み出すよ
  • 起動時にコンフィグ
    • 補足: なおZynqとかだと起動後に別途コンフィグもできる

FPGA 基礎の基礎

論理の表現

  • 図とかなしにどう説明しようかなと思い
  • すごく雑に仕組みを説明すると、カンペ+メモ帳
  • AND回路とかOR回路とかふんわり分かればFPGAの仕組みは分かります
    • ANDは、全部の入力が1の場合のみ1を出す、それ以外は0
    • ORはどれか1つでも1だったら1を出す
    • NOTは入力が1なら0を、0なら1を出す
  • これをFPGAはカンペで実現する
  • まずはとても単純な、1値の入力で1値の出力をおこなうものから考える
    • NOTをあらわすカンペには1→0 0→1と書いておく
  • 2値以上でも基本は同じ
    • 2値のANDなら0・0→0、0・1→0、1・0→0、1・1→1というカンペを書いておく
    • 6値の入力から1bitの出力を作る、と考えると64パターン。結構複雑な回路が作れる

フリップフロップ

  • (フリップフロップ、一度手組でもしないと自分の中のイメージきちんと固まらないのでは)
  • 要はメモリです。次のクロックが来たタイミングで、つながってる先へと値を渡す役割を持ちます

配置配線

  • ゲート数がいっぱいあればいい感じに動く?動かない
  • 配線が大事になる
    • FPGAのクロックはナノ秒単位
    • あるユニットから他のユニットへどれぐらいの時間で信号が届くかが大事になる
    • 配線が異常に長い部分ができると、その信号が到達するのを他の部分で待つ必要が生じる
      • クロックを落とせばいいけれど、そうするとシステムの動作速度が下がってしまう
  • どこのゲートにつなぐか(配置配線)はFPGAベンダーのツールでやる
  • 書き方によって生成される配線も変わる
    • ここは職人芸(経験とカン)

FPGA上にあるロジックセル

  • 数は200万とかある
  • Flip-Flopでも消費されたりする(SRAMとして使ったり)。小規模なものならいくつか入れられたりする
  • 全部をプリミティブに組むのはあまり効率が悪い
  • 加算処理をする専用の回路とかが予め含まれるようになってきている
    • キャリーフラグなども流せる

Alteraがここしばらく(数年)力を入れてきたFPGA上の最適化

  • ロジックセルは8値の入力から2値の出力というのが基本セット
  • これを4値入力1値出力 2セットというふうにも使えるようになっている
    • 補足: 限られたロジックセルを有効に使って柔軟に回路構築をできるというウリ
  • 考えてみると、ここの最適化を人力でやるのは非常につらい
    • 他のベンダーがいきなり入ってきてちゃんとしたツールセットを提供するのもむずい

論理合成・配置配線

  • 最適化問題。むずい
  • 肌感覚、割と単純な回路でもMacBook Proで4-5分とか合成/配置配線にかかる
  • 複雑なのを作りたければ高いの買え的な?
    • 同じアーキテクチャ世代でも回路規模によって値段が全然違う
  • 回路規模が大きくなると合成も時間がかかりすぎて個人では無理なのでは?
    • ツールのお高い版には分散処理をする仕組みが含まれていたりするらしい
  • ツールはFPGAボードごとに別? → XilinxとAlteraでそれぞれ1種類ずつ持っている

プログラムを書いて合成していく

  • VHDLとかVerilogとかで書く
    • アセンブリ言語なイメージ
  • コードが上から順に実行されるわけではない
  • あるブロックをまとめて実行する
  • この性質を使って、パラレルにできる部分はパラレルにする
    • 例えば16個の入力それぞれに4ずつ値を足すような処理は、それだけ分の回路を割り当てれば同時に処理できる
    • FPGAで高速化できるパターンの半分ぐらいはこれだと思う(主観)
    • 行列計算とかいい感じにできる
    • ハードウェアとソフトウェアのいいとこ取りができるエリア

FPGAつらい話

  • VHDLやVerilogでいきなりBingのランキング処理書け!とか言われてもつらい
  • Xilinxのツール、生成した回路の中でネックっぽい場所は見つけてくれる
  • VHDLやVerilogはアセンブリ言語みたいな立ち位置、これで大規模なアプリを作るのは辛い

FPGAのざっくり開発工数

  • より高級な言語で書けばいいのでは?という感じもする→後で出てくる
  • Xilinxの人による2012年の講演資料: FPGA 2032 Roadmap: A Personal Perspective
    • CPUだと1時間で書けるような処理にFPGAだと1週間ぐらいかかる。その段階で1時間かけて作ったコードの4倍ぐらい速い。いっぽうCPU側も1週間ほど続けると更に4倍速いあたりになる
    • FPGAを採用してうまみのある部分は数ヶ月間かけてチューニングしていくようなもの
    • 最初の立ち上げはCPUで書いて、後から時間をかけて最適化していくのにFPGAを使うなどがモデルとして良さそうという話
      • 「相当なコストをかけても、それだけのリターンがあれば使いたい」という領域にしか当初は使いにくい→最たるものが金融
  • 細かく辛いところ: コンパイルに時間かかる
    • 多少コード書き換えてコンパイルし直しに5分とかかかると辛い

OpenCores

  • 開発効率がなかなか上がらない点は、再利用可能な部品がいっぱいあると効率よくなるかも
  • OpenCoresというプロジェクトではIPを公開している

GPUを使う話

  • GPGPUとかGPU Computingというエリア
  • さきの資料、1週間ぐらいかけてできるFPGA実装よりも4倍ぐらい速い状態(CPU実装の1週間分あたり)が、GPUだと2日程度でできるよという話
    • 最終的にスケールする度合いもFPGAと結構近いとされている
  • FPGAほど辛いことやらなくても良いかも
  • GPUでいいんじゃない?ってなる

高位合成

  • FPGA向けのハードウェア設計をもっと書きやすい言語で書けるようにする
  • CとかからFPGAのデザインを作るのを高位合成と呼ぶ
    • ここがホットなエリア
  • ものによってはCで書かれたコードをなるべく並列化して最初のデザインを仕上げるというもの
    • Cだけではない。Haskellからの高位合成もある
      • 型がしっかりしているし、もともと並列処理に向いているし
      • Lavaというのがある(Kansas大学あたり)→Xilinx版もメンテされてる
  • 竹井さん: 以前やったところだとSystemC、変換効率がさほどよくなかった
  • 竹井さん: VHDLを書いていると「こんだけ書いたのにまだこれだけしか動かない」となる
  • ボトルネック部分を手動で頑張るような感じになると良い
    • Pythonの拡張みたいな感じ
    • そういえばPythonからの高位合成を研究している
  • XilinxのツールセットでもVivado HLSというのがある
    • 25万円ぐらいのエディションでないと使えない
  • Lavaあたりで論理合成を先にやってしまって、実際のFPGAボードにあわせた配置配線だけXilinxあたりのツールでやるとかも現実的かもしれない
    • 補足: ここは、IP-XACT(IEEE 1685)あたりで書きだしたものを各種ツール側でインポートするのを想定している

開発環境

  • 今は開発しているコードの情報などをXilinxやAlteraへと共有する(これを売り渡すと表現している)代わりに無料で使える範囲が大きい
  • XilinxのSUZAKUというシリーズを使っていた。これには1年分のライセンスがくっついてきてた
    • Zynqも似た感じ

高位合成が普通になると、FPGAはGPGPUと張り合える?

  • 基本的には両方が選択肢になるのではと思っている
  • FPGAとGPU、少々特性が違う
  • GPUにもつらさがある
    • GPUで処理するためにメインメモリからデータを転送し、GPUでの処理を終えてからCPU側へ引き上げるのにレイテンシがかかる
      • このコストを上回るほどGPGPU側の処理が速ければペイする?というのを考える必要がある

GPU側も進化していっている

  • GPUも進んでいるエリアがある。CPUとGPUを統合する向きにある
    • AMDだとAPU(Accelerated Processing Unit)と呼ばれる
  • CPUメモリとGPUメモリを統合する向き
    • CPU側とGPU側のメモリをリニアに共有する形になっている
    • CPU側でデータを作り、GPUには場所だけを伝えるとGPU側から直接データを読み出して処理、結果アドレスをCPUへ返して直接利用できるようになっている
    • AppleのA7あたりでも似た話
      • Metalは描画コマンドの送り方が違うなどの他にも、CPUから書き込んだメモリをGPU側で直接読み出して処理するようなモデルが整備されている
  • GPU統合CPUというモデルがハイエンド化していくのでは
    • これまでは安いノートPC用というイメージだった
    • メインメモリの一部をGPUに割り当てていたが、従来だと垣根があった
  • GPUも進化している
  • FPGA一人勝ちという感じはしない

FPGAとCPUがミックスされたようなもの

  • 昔だとFPGAの中に小さなCPUコアを構築する形だった
  • 最近は逆、というか普通にARMのCPUが載っていて、それに加えてFPGAも載っている形のものをXilinx(補足: Zynq)もAltera(補足: FPGA & SoC)も出している
    • ARMのCPUに自分で拡張命令を実装して、それを普通にLinuxなどから呼び出せる
  • 中澤が最近やっているのはARMv8に載っている拡張命令をFPGA側に実装してARMv7でも使えるようにするというもの。なかなかパフォーマンス上がらない
    • どこから手を付けて良いかよくわからず、ツールの使い方で苦労した
    • 数十年間練られてきたツールだけに、慣れないとなかなか効率があがらない(補足: PlanAhead+Vivadoで15年ぐらい?)

竹井さん: FPGA学習の仕方 / Design Wave

  • FPGAな人向けのやつ
    • 最近のツールの使い方とか説明してた
  • 最近だとFPGA Magazine
  • Design Wave 2009年の最終号
    • (ここで主要トピックが「Cベース設計の時代がやってきた」となってたあたりがとても趣深い)
  • もう10年ぐらい前だと、5万円でめちゃくちゃショボいボードを買って触ってた
  • ucLinux(MMUの要らないもの)をMicroBlazeで動かしていた
  • 秋月で売ってた液晶を買ってきてコア拡張した部分の物理アドレスへデータを書き込んで画面表示する
  • 大学の研究室で、ディスプレイ出力とか諸々全部含めてシューティングゲームを作る的なのやってるひといた
    • 敵のスプライトを移動させるとかそういう処理も
  • 大学の演習でCPU作るところからやるのとかあるという話

クロージング: まずはここから

  • 最近話題になっていた$30のボードがあるのでそれで($30で始めるFPGAが素晴らしい資料)
    • 8000ロジックエレメントでできることを考える
    • 飯塚さんが小さなCPUを作るのを目標にする

blogをRe:VIEWで書くことを考える

2015年4月24日金曜日

これまでblogの下書きにEvernoteを使ってきたのですが、最近Mac版Evernoteが重すぎる(日本語タイピング時、文字が数秒遅れて表示される)ので段々と思考の邪魔になってきました。この用途ではEvernote捨てたいです。
一方、Bloggerのエディタもだいぶ酷い出来です。それを補うためにごちゃごちゃしたHTMLタグを手動でいじるのも不毛です。
こういう需要に対して、Markdownが有力な選択肢でしょう。.mdを食わせると.htmlを吐き出してくれるコンバータもひとつやふたつではないし、はてなブログだってMarkdownでの記述をサポートしています(制限もありますが)。利用人口それなりに多そうです。
そんななかRe:VIEWでblogを書きたいと思ったので、要件を考え、下調べをおこない、最低限の手動運用をできるようにしたところまでが今回の話です。