C#のSystem.Runtime.Intrinsics.X86.Avx2、結構微妙な気がする。特にC++とかではキャストで結構いろいろ騙せるけど、C#だとVector256<T>とかでラップされてるので、型が違う演算を行えない。Shuffleで32x8bitを自由に入れ替える機能を使って16x16bitを操作する、みたいなことができない気がする。キャストとかでゴリ押しすればそれっぽいことはできるけど。
とりあえず、Avxでfloatのクロス積は取れるようになった。なんか冗長な感じもするけど、いちおうComplex32.Multiplyチマチマ呼び出しと比べて2割ほど早いので、多少は効いてる。なにが効いてるのかはわからんが。MathNet.Numerics.Complex32ってSIMD対応してるのかな。対応してるならなんでオレオレ実装が早いのか謎だし、非対応なら2割程度しか改善してないのは効果低いし。自作Corssのunsafeの中でfor回したら9割くらい早くなるし、単純に関数呼び出しのコストや境界チェックが効いてるだけな気もする。
本来やりたい計算は16bit整数のクロス積でいいので、それが実装できれば2倍位早くなるはず。16bit整数のPermuteが無いのが謎い。なんで無いんだ? 誰も使わないから? そんなことは…… C++なら8bit単位のShift使えば済むからかな。とはいえ、8bit単位のマスクを使ったシフトも、メモリアクセスとか考えると結構性能悪そうな気がするし、別のやり方がありそうな気がする。
試しにIDEのプロファイラで調べてみたら、CICの加算が計算時間の大部分を占めているらしい。CIC/FIRは自作のComplexI64を使っている。確かに、CICの前半部分の和は、その前のComplex32の積のN倍(NはCICのタップ数)なので、これが大部分を占めるのは説得力がある。昨日試した、Complex32の使用で高速化がほとんど効果が出なかったのも納得。
ということで、まず狙うはCICの計算の最適化、ということか。しかしなぁ。long型の複素数の加算なんて、どーやって最適化すればいいやら。それこそ.NET Coreに移行してSIMD使うくらいしか思いつかない。
とりあえず明日はCICの最適化をちょろっと試してみて、様子を見つつCoreの移植も試してみよう。
***
3月11日受信分
* 27844 / CUTE-1
* 27848 / XI 4* 28895 / XI 5
* 32785 / CUTE-1.7+APD II
* 32791 / SEEDS
* 33493 / PRISM (HITOMI)
* 35932 / SWISSCUBE
* 41460 / AAUSAT 4
* 42775 / AALTO 1
* 42790 / VZLUSAT 1
* 42792 / ROBUSTA 1B
* 43615 / CP-7 DAVE
* 43743 / REAKTOR HELLO WORLD
* 43933 / ORIGAMISAT-1
* 44330 / RAAVANA1
* 44909 / BREZE-KM R/B
弱いけど40380/EXOCUBEと47721もなんかそれっぽいの受信してる。この2つは多分初めて受信した。後者は先月末に打上げられた新顔。CWじゃなくなにか変調かかってるようなスペクトルだけど、かなり弱い。固定ビームなので受信強度は目安にもならないけど。
0 件のコメント:
コメントを投稿