FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

自作RISC-V CPUコアで構成を変えながら性能を測定していく (3. Dhrystoneのボトルネック解析ツール)

自作RISC-V CPUコアの方は、いくつかのコンフィグレーションにおいてDhrystoneを完走させることができるくらいになってきた。 次に、どこがボトルネックになっているのかを見てみるために、いくつか性能ダンパーを追加することにした。

基本的に見てみたいのは、どのキューがいっぱいになっているのか。例えば1000サイクルの間で、どのキューがどの程度のサイクルいっぱいになっているのかが分かれば、性能改善の余地がある。

  • 命令バッファエントリ
  • ROBエントリ
  • ALUのスケジューラエントリ
  • LDQスケジューラエントリ
  • STQスケジューラエントリ
  • BRUスケジューラエントリ

について、平均的なエントリ充填率と、エントリがいっぱいになった時間を測定する。

例えばLDQの場合はこういうようなエントリロガーを実装する。

logic [63: 0] r_cycle_count;
logic [63: 0] r_ldq_max_period;
logic [63: 0] r_ldq_entry_count;

always_ff @ (negedge i_clk, negedge i_reset_n) begin
  if (!i_reset_n) begin
    r_ldq_max_period  <= 'h0;
    r_ldq_entry_count <= 'h0;
    r_cycle_count  <= 'h0;
  end else begin
    r_cycle_count <= r_cycle_count + 'h1;
    if (r_cycle_count % sim_pkg::COUNT_UNIT == sim_pkg::COUNT_UNIT-1) begin
      r_ldq_max_period  <= 'h0;
      r_ldq_entry_count <= 'h0;
    end else begin
      if (|w_ldq_valid) begin
        if (&w_ldq_valid) begin
          r_ldq_max_period  <= r_ldq_max_period + 'h1;
        end
        r_ldq_entry_count <= r_ldq_entry_count + $countones(w_ldq_valid);
      end
    end // else: !if(r_cycle_count % sim_pkg::COUNT_UNIT == sim_pkg::COUNT_UNIT-1)
  end // else: !if(!i_reset_n)
end // always_ff @ (negedge i_clk, negedge i_reset_n)

function void dump_perf (int fp);
  $fwrite(fp, "  \"ldq\" : {");
  $fwrite(fp, "  \"max_period\" : %5d, ", r_ldq_max_period);
  $fwrite(fp, "  \"average count\" : %5f},\n", r_ldq_entry_count / 1000.0);
endfunction // dump_perf

これを1000サイクルに一回、各モジュールに対して送信して情報を取得する。

  "inst_buffer" : {  "max_period" :   146,   "average count" : 4.058000},
  "rob_entry" : {  "max_period" :     0,   "average count" : 9.331000},
  "ldq" : {  "max_period" :    37,   "average count" : 8.216000},
  "stq" : {  "max_period" :     0,   "average count" : 5.438000},
  "alu" : {  "max_period" :     0,   "average count" : 5.368000},
  "alu" : {  "max_period" :     0,   "average count" : 2.608000},
  • 命令バッファは1000サイクル中146サイクルで埋まっている。エントリ自体は8個あるのだが、これは改善の余地がありそう。ちなみに平均で4個しか埋まっていないので、何らかの段階で命令バッファが埋まってしまっている。
  • ROBを使い切っている場面はない
  • LDQはちょいちょい使い切っている。
  • それ以外のエントリは使い切っていない

つまり、命令バッファによる命令供給能力にそもそも問題がありそうだということが分かってくる。もう少し解析したい。

命令バッファが埋まっている様子