ARM Linuxカーネルの中でNEONのSIMD命令を使用する方法
Linuxカーネルの中ではFPUを使った浮動小数点演算を一切行いません。カーネルのコードの中でFPUにアクセスするのはFPUレジスタの退避、復帰だけです。
NEONのSIMD命令はFPUレジスタを使用します。そのため以前はカーネルの中ではNEONのSIMD命令を使用することはできませんでした。しかし、RAIDや暗号化などカーネルモジュールの中でもSIMD命令が効果的なものもあります。
そこで、v3.12からkernel mode NEONという機能が追加され、ある決まった手順に従うことでカーネルの中でNEON命令が使えるようになりました。
詳しくはこのドキュメントを参照してください。
Documentation/arm/kernel_mode_neon.txt
軽く中身を紹介します。
カーネルの中でNEON命令を使用するには、まずその部分だけを別のソースファイルにし、そのファイルのコンパイルオプションを -mfpu=neon -mfloat-abi=softfp をつけます。(必要に応じて -ftree-vectorize も。)
カーネルのそれ以外の部分はFPUの使用を避けるため、-fsoft-float のオプションがついています。
次にソースコード中のNEON命令を使用する部分を kernel_neon_begin(); とkernel_neon_end(); ではさんでください。
kernel_neon_begin(); ... ここでNEON命令を使う ... kernel_neon_end();
kernel_neon_begin(); からkernel_neon_end(); の間ではそのCPUコアでのコンテキストスイッチは禁止されます。そのためこの間はNEONの演算だけに集中し、I/O待ちなどsleepの発生するコードは書いてはいけません。
逆にこのような制限をつけることで、FPUレジスタを退避復帰することの煩雑さも無くなっています。