プロファイル

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という関数が簡単そうなのでやってみます。