-
Accelerateとsimdを使う
洗練された信号処理と画像処理のテクニックを使って、Appのパフォーマンスを改善させつつ、バッテリー消費を抑える方法について学んでいきましょう。インタラクティブなデモを通して、Accelerateフレームワークの優れたユースケースについてご確認ください。また、Appにベクトルプログラミングを簡単に導入する上で役立つ、simdについても紹介します。
リソース
- Improving the quality of quantized images with dithering
- Rotating a cube by transforming its vertices
- Halftone descreening with 2D fast Fourier transform
- Signal extraction from noise
- vImage
- simd
- vDSP
- Accelerate
- プレゼンテーションスライド(PDF)
関連ビデオ
WWDC19
-
このビデオを検索
(音楽)
おはようございます
(拍手) エンジニアの マシュー・バディンです AccelerateとSIMDの セッションへようこそ
同僚のチャンと 私が担当します Accelerateが可能にする APIについてお話しします まずはAccelerateの ハイレベルな概要から始め ライブラリを 詳しく紹介します まずはvDSPの例を 2つ紹介します ノイズから信号を 取り出す方法 画像のアーティファクトを 取り除く方法です
次にSIMDへ目を向け 四元数を用いた 三次元回転を紹介します
その後 ルーク・チャンが Vimageの機能を紹介します では早速始めましょう
まず最初の議題は “Accelerateとは何か?”
Accelerateは大量の プリミティブを提供します 全プラットフォームが 対象です iOSやmacOS watchOSやtvOSも含みます
これらはマイクロ アーキテクチャに組み込まれ 快適な動作を実現します
また省エネにも 役立っています
Accelerate フレームワークを使えば アプリケーションは速くなり バッテリーも長く持ちます ユーザの満足度も 上がるでしょう
多くのプリミティブを 扱う場合 各ドメインに グループ分けすると便利です
例えば信号処理された プリミティブはvDSPへ 例えばFFT またはDFTとDCTですね 高速フーリエ変換や 離散コサイン変換です
画像処理の プリミティブもあります 色空間変換で使う ライブラリです
vForceは ベクトル型超越関数 サインやコサインです
また高度の線型代数学と
疎行列も可能です
BNNSという ニューラルネットワークは ライブラリで管理します Accelerateではありませんが 関連の深いライブラリです SIMDもこれに含まれます CPU用のベクトル計画法です Compressionには 可逆圧縮機能があります
まずはvDSPについて 説明します
信号処理プリミティブを含む 最新のライブラリであり 足し算や引き算などの 基本的な算術演算 より複雑な演算の例は 畳み込みやフーリエ変換です
アプリケーション開発者にとって フーリエ変換は厄介ですが Accelerateを使えば簡単です いくつかの コード行を入れるだけ 例があります ノイズから 信号を取り出します
これはオーディオ信号です まだノイズは加えていません 下にスライダがあります 左下でノイズを加えます
入りました
右下でノイズの除去が 可能です
しきい値です
右下にトグルスイッチがあり
異なるドメインを表示します 今はタイムドメインでの 表示ですが 周波数ドメインで 信号を見てみましょう
左側に山形があります これらが周波数成分です
青の直線もあります しきい値なので 動かしてみます
これから信号に ノイズを加えます もっと加えましょう
私が注目しているのは 左にある山形です 一番高い 山形ともいえます 加えたノイズは背景雑音です 低い山形が ほぼ均等に並びました
ではノイズを取り除きます しきい値を 少しだけ上げます
何が起きているのかというと しきい値よりも低い 周波数成分が削除されます 青い直線よりも 低い山形があれば ノイズと認識されます
さらに上げます
ノイズが消えました
タイムドメインでも ノイズは消えています ここで しきい値を外すと 元のノイズ入りの 信号が表示されます
やり方を解説します
最初にすることは 信号の解析です スイッチを使います それから周波数成分の ノイズを見つけ除去します 最後にオーディオ信号を 再構築します 次はコードです
使うのはDCT 離散コサイン変換です
DCT CreateSetupが 見えますね
コンテキストでタイプと 空き容量が分かります
今回はDCT タイプ2を使います
コンテキストを実行すると
解析が行われます
解析後はノイズを除去します ここがポイントです
しきい値よりも 低い周波数成分を探し ゼロにしてしまいます
最後は オーディオ信号の再構築
再びCreateSetupを使います
今度はDCTタイプ3で 再構築を行います
コンテキストを実行すると オーディオ信号が 再構築されます
一例として
オーディオ信号から ノイズを取り除きました 次に画像からノイズを 除去する方法をお見せします
古い新聞の写真の 復元を試みます
画像を取り込み
白黒のスクリーンを 適用します
古い新聞の写真と同じです これからスクリーンを 取り除きます アーティファクトの除去です 今は何もしていません まずはサンプルを取り出し マスクを作成して 画像に適用させます やってみましょう
今は周波数成分を 認識しているところです しきい値よりも高い 周波数成分を
除去します
しきい値が低いと
アーティファクトに加え 画像も消えてしまいます
次は高くします
変化がありません
中間にすると アーティファクトだけが 除去されます 画像には ダメージを与えません まとめます
画像とサンプルに 高速フーリエ変換を施します サンプルからマスクを作成し 画像に適用させ
オリジナル画像を 再構築します 次にコードです
FFTを使います
パワー2なので ログ2を呼び出します
画像のサイズは 1024×1024です
これをfft2d zropに 落とします opは“置き違い”です このため仮の スペースを作ります
複雑な数列構造を2つの 列に分けて保管するのです 実際の成分と架空の成分です
方向も指示します 今回はforwardです
アーティファクト除去は さらに複雑なので 上級者向けにお話しします サンプルはオンラインで 取得できます vDSPの項目に工程を解説した ドキュメントもあります
まずサンプルの周波数成分の 大きさを割り出してから
除去する成分も確認します
そこからマスクを作成し
元の画像に適用させます
除去したい成分に0を掛け 残したい成分に1を掛けます
zropで画像を再構築します FFTはコンテキストを 再利用できます
重要なのは2つの配列に 画像を保存すること それほど複雑です 偶数画素は実際の列 奇数画素は架空の列です
今回は逆高速 フーリエ変換を行います
少し話を移します 2つの例を見せましたね
先にvDSPの活用例を見せ それらの作成方法を あとから説明しました 結果と説明が逆でしたね 次は基本的な 成分から始めます 結果は最後です 今度はSIMDです 低水準の基本的な プリミティブを回転させます 3D物体の回転です
SIMDの特性は
ベクトル処理ユニットの 抽象化です ベクトルおよびマトリクス 対象を宣言させ 対象を編集可能にし ハードウェアへ導きます
コードを見せます
2つの配列を使い 成分の平均を割り出し 成分を繰り返し足しては 2で割っていくのです
大変な作業です
配列をSIMD float4 ベクトルタイプに
宣言することで対象物の 計算が可能になります
算出が滑らかになり 高速計算が可能となります
全プラットフォームで 可能です
他にも機能があります ベクトルおよび マトリクス対象物の
高度な計算を可能に するだけではありません
例えばドット積と clamp関数です
サイン コサインなどの 超越関数や
四元数もです 四元数は3次元での 回転に利用できます 詳しく解説しましょう
コードの例を見ていきます
少し複雑です まずは右から グレーの 単位球面があります 赤い点が見えますね
ベクトルの先端です
SIMD float3を宣言し xとyを0に zを1に設定します こちらに出てきますね 赤い点はベクトルの先端です
四元数を使って ベクトルを回転させます
実際は全体を回しますが ここではベクトルとします
四元数を使うため 軸と角度を設定します 何をどれだけ 回転させるかということです xを軸に3ラジアン分のπ 上昇させましょう
act functionを呼び出し
四元数を実行すると ベクトルが回転します
やってみます
皆さんは複数の軸を使っての 回転に興味があるでしょう
通常の回転 マトリクスと同様に
掛け算を用いて 回転させます また掛け算は 可換ではありません 演算対象を変更する際 位数も変えます
3ラジアン分のπ 上方に動かし 同様に右へ動かします これを1つの動きにします
四元数でできることに 補間があります 2つのタイプの補間です
まずはSlerp
球面線形補間のことで
異体が2つあります
simd slerpは最短の弧で 青と緑を結んだもの
simd slerp longestは 最長で背面に回っています
次はSplineで 複数の回転を行うのに 便利です では複数の回転の 配列を補間します Splineのコードだけに 注目してください
個々の回転を反復して Splineに適用させます
従って補間したい2つの 回転だけではなく 前後の回転を含めます
こうなります
ゲーム開発者であれば 対象物を回転させたいはず それも可能です 複数のベクトルで 表された立方体が 8種の回転を行います 左はSlerpを右はSplineを 使ったものです まずはSlerpから
線形補間のため 動きが角ばっています 次はSplineです
前後の回転も認識し なめらかな動きです ではもう一度
少し駆け足でしたが 振り返ります
最初にvDSPの 2つの例を見ました ノイズから信号を取り出し 画像からアーティファクトを 除去しました
次にSIMDで四元数を用い 3次元での回転を見せました
次はルーク・チャンが 担当します Vimageの活用法についてです (拍手) ありがとう
私はルーク・チャン Vector and Numericsの エンジニアです 今回は Vimageについてお話しします 機能と利便性についてです わずかなコード行で 動画にエフェクトを入れます 始めましょう
Vimageは 画像処理ライブラリです いくつかある機能の内の 1つは転換機能です フォーマットの異なる画像を 転換することができます フォーマットには それぞれ利点があります RGBはディスプレイの 画素と相性がよく 背景画面に最適です 一方でYCbCrもあります 人の視覚に近いのが特徴です 明るさを認識する 輝度チャネル 色を認識する クロミナンスチャネル カメラは YCbCrを使っていますね
転換機能でフォーマット間を 移動可能にします
次に形状機能です 画像のサイズや 位置の変更が可能になります vImageScaleを使って 画像の拡大縮小ができます ランチョス法アルゴリズムで 高品質な仕上がりです vImageRotateでは 画像の回転が可能です
次に畳み込み機能です この機能の一番の特徴は ぼかし効果です UIや写真では よく見られるエフェクトです 何かを背景へぼかしたい際に このエフェクトを使います
そして変換機能です 基本的には 行列の乗法のことで 各画素のデータチャネルに 対応します 例えば赤や緑を 強くしたい場合 変換機能が役立ちます
形態機能 この機能で対象物の サイズや形を変更できます 対象物のみです vImageErodeと vImageDilateで 拡大縮小ができます 冒険をしたければ カーネルの形を 各機能に反映させます するとErodeとDilateは 対象物の拡大縮小を カーネルを元に行います
これらが5つの機能です これからVimageの デモアプリケーションで エフェクトを紹介します
これは端末の 背面カメラで映した映像で スクリーンに投影させました リアルタイムの ライブ映像なので バラの横で水飲み鳥が 動いていますね まずはサチュレーション エフェクトです これは他社の画像編集 ソフトでもよく見られます 色を鮮やかにしましょう このスライダを 右へ動かします
赤はより赤く 緑はより緑に
また左側に 白いバラがあります この色は あまり面白味がありません この映像で 注目してほしいのは 構図と色のコントラストです 左へスライドさせて 彩度を下げます
映像が白黒になるまで スライドさせると 色は もう気になりません 構図とコントラストのみ 注目されます
では やり方を解説します
いくつかステップがあり まずはカメラで 画像を撮影します
次にVimageを使うための 準備として 出入力バッファを用意します
Vimageの機能で エフェクトをかけ
スクリーンに出力します
先にVimageを使った エフェクトの話をしましょう
サチュレーション エフェクトは こちらの方程式を使います 基本的には 画素からバイアスを外し 掛け算を使って エフェクトをかけます そしてバイアスを戻します
Vimageは この作業を行うのです vImageMatrixMultiplyと いいます
まずは プリバイアスを取り出し 例では-128ですが これでバイアスを除きます
彩度は点が浮いていますが 画像は整数値です 彩度の値を定点に 変換する必要があります Q12を定点とすると 除数は0×100となります
ポストバイアス×除数で バイアスを画素に戻します
マトリクスはシンプルです CbCrチャネルを スケーリングします マトリクスはスケーラーで CbCrチャネルを掛けます
vImageMatrixMultiplyを 呼び出すと 1つの配列と1つの機能で エフェクトがかけられます
ではステップに戻ります
カメラから 画像を取り出すには
デリゲートを使います カメラから CV画像バッファを取得し バッファを手に入れます CPUでアクセスが 可能か確認します そこにVimageがあります どんなエフェクトを かけたあとも バッファのベースアドレスを アンロックします これでメモリを 再利用できます
次のステップでは 出入力バッファを準備します
CV画像バッファがあるので 情報を取得するだけです 高さや長さなどですね
これをVimage バッファ対象とし ライブラリで使用します 輝度とクロミナンス チャネルのためです
そして出力バッファを 用意します メモリは まだ出力画像に 配置されていません Vimageには 便利な機能があります 正確にはVimageバッファです
高さと長さ 1画素のビット数を与えると 画像の保存に十分な メモリを配置します さらにバッファ 対象物を作成し ライブラリ内での 使用が可能になります
最後のステップで 画像をスクリーンに移します
すでにお話ししましたが RGBは ディスプレイに最適です では転換機能を使って YCbCr画像を RGB画像に変えます UIはCGImage対象物に 対応するので 新しく作ります
Vimageの機能で CGImageCreateがあります
Vimageバッファから CGImageを作成します 特筆すべき点は 大きなデータバッファを コピーしていないということ CGImageを単に作成し 画像バッファの 容量を足しています 必要な情報を提供し CGImageを作成しているので コピーは不要です
作成したCGImageを イメージビューに送ると スクリーンに投影されます 簡単です 4つのステップで エフェクトを加えます 例は彩度でしたが Vimageの他の エフェクトも紹介しましょう
時計回りと反時計回りに 画像を回転させることと 背景への ぼかし効果も可能です 画像にレトロな 質感を出したいと感じたら ディザリングで 白黒にできます カラー画像は 量子化も可能です アプリケーションでの 操作をお見せします
回転を操作する スライダがあります 映像を反時計回りに 回転させたり
時計回りの回転も可能です
次に ぼかし効果です ここをクリックして 段々とぼかしていきます
左にスライドさせれば 再びバラを前面に戻せます
ディザリングで白黒にします
この白黒映像のグレー部分は 点の密集によって 表示されています ディザリングです アクセントとディザリング アルゴリズムは のちほど解説します
カラー量子化は 参照テーブルがあります スライダで 量子化レベルを上げます 右に動かしていくと 映像の色が どんどん減っていきます 独創的な映像です
80~90年代の パソコンの画面のようです
それでは今から やり方を説明します
回転はvImageRotateを 呼び出し 角度を設定します 時計回りも 反時計回りも可能です
ぼかしは TentConvolveです カーネルのサイズが重要で 大きいほど ぼかしが強くなります
ディザリングは画像を 8ビットから1ビットに変え アルゴリズムも選びます ここではアトキンソン ディザリングを使います
カラー量子化は RGBチャネルのために 参照テーブルを作成します vImageTableLookUpを 呼び出し 参照テーブルを適用し 色の数を限定していきます
4つのエフェクトを 紹介しましたが ここからは次のトピックに 話を移します
LINPACKベンチマーク
Accelerateの機能は アプリケーションでの 利用も手軽だと話しました しかし速度に関しては 話していません そこでLINPACK ベンチマークです
一体何をするのか 連立一次方程式を解く 速度を計るツールです 実際には3種類あります 行列を100に固定して 計測するもの 行列を1000に固定するもの 最後が これからお見せする タイプのもので 無制限です どんな行列でも可能です 機械の計算能力を 最大限に使っています
iPhone XでAccelerateを 使ってみましょう
速度はギガフロップスです
倍精度は iPhone 5Sから上がり iPhone 6
iPhone 6S iPhone 7 そしてiPhone Xは 28.7ギガフロップスです これが倍精度で 単精度も見ましょう
そうですね
はみ出したので チャートを縮めます
iPhone Xは 68ギガフロップスです 別に驚くことでは ないかもしれません 精度もパフォーマンスも 改良されていますが それだけではありません
マイクロアーキテクチャで 計算能力が上がり 高度な計算能力を 使うソフトが必要となります そこに注目しました 同じLINPACKベンチマークが 5つのiPhoneで実行できます Accelerateで得られる 最適な動作環境
アプリケーションも同様です Accelerateを使えば 最適な動作が保障されます すべての アーキテクチャで可能です
異なるプラットフォームも Accelerateが利用できます macOS iOS tvOS watchOSで可能です
新しいアーキテクチャや プラットフォームが出ても 心配は要りません その際に必要な作業は1つ Accelerateに リンクさせるだけです これで最新の アーキテクチャや プラットフォームも 快適に使用できます
最後にまとめます Accelerateには 様々な機能があります 想定以上のことが 可能なのです 機能が不十分であれば リクエストを送ってください 送られたものは検証し 開発に役立てます リクエストから生まれた 機能はたくさんあります
Accelerateは手軽です 大抵は機能を 呼び出すだけです
高速かつ省エネであり アプリケーションは速く バッテリーも長く持ちます
Accelerateは移行が可能です 全プラットフォームと 全アーキテクチャにおいて 最適なパフォーマンスを 保障します コードの変更は 必要はありません
developer.apple.comにて 詳細が確認できます デモアプリケーションや コードなども取得可能です 明日は ラボセッションがあります とても楽しみです Accelerateに関する 質問があれば 明日 聞きましょう
では本日は ここまでです よい1日を (拍手)
-