プロファイル
SIMD化するにあたり、どの部分の処理が重いか把握するためgprofを使いプロファイルを取ってみました。spuパートを-pgオプションを付けて実行してみましたが、プロファイル情報のファイルが見当たらないので(そりゃーspu側からどうやってファイルを作るの?ってところ)、i386で実行した結果です。MMXを使わず実行した結果です。長いので上位部分のみの抜粋です。
Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 14.59 1.80 1.80 1024067 0.00 0.00 quantize_xrpow 8.91 2.90 1.10 18178 0.00 0.00 L3psycho_anal_ns 8.51 3.95 1.05 4562622 0.00 0.00 count_bit_noESC_from3 7.70 4.90 0.95 7913209 0.00 0.00 ix_max 7.17 5.79 0.89 46244832 0.00 0.00 mask_add 7.05 6.66 0.87 617414 0.00 0.00 calc_noise 5.59 7.35 0.69 45784 0.00 0.00 filterYule 5.11 7.98 0.63 145424 0.00 0.00 fht 4.21 8.50 0.52 36356 0.00 0.00 init_xrpow 3.57 8.94 0.44 2384551 0.00 0.00 count_bit_noESC_from2 3.57 9.38 0.44 218136 0.00 0.00 compute_masking_s 2.51 9.69 0.31 45784 0.00 0.00 filterButter 2.43 9.99 0.30 1024067 0.00 0.00 noquant_count_bits 2.27 10.27 0.28 591557 0.00 0.00 amp_scalefac_bands 2.19 10.54 0.27 72712 0.00 0.00 compute_ffts 1.94 10.78 0.24 654480 0.00 0.00 window_subband 1.30 10.94 0.16 22604417 0.00 0.00 fast_log2 1.13 11.08 0.14 802011 0.00 0.00 count_bit_ESC 1.13 11.22 0.14 107822 0.00 0.00 Huffmancode 0.89 11.33 0.11 9090 0.00 0.00 mdct_sub48 0.73 11.42 0.09 12427470 0.00 0.00 putbits2 0.65 11.50 0.08 601495 0.00 0.00 scale_bitcount 0.65 11.58 0.08 9090 0.00 0.00 lame_encode_buffer_sample_t 0.57 11.65 0.07 9090 0.00 0.00 fill_buffer 0.49 11.71 0.06 7913209 0.00 0.00 choose_table_nonMMX
この結果を元にループで連続データの処理を行っているところからSIMD化していきます。処理が重い部分と数多く呼ばれている部分がターゲットです。ざっと見た感じではix_maxという関数が簡単そうなのでやってみます。