標準境界ピクセルたたみ込み

たたみ込みの最後の段階では、境界周辺のデータを作成します。これらのピクセルは、たたみ込み出力の最も近いピクセルを再利用することにより作成されます。次の図に、これをどのように達成するかを示します。



境界領域は、最も近い有効な値を使用して作成されます。図に示す操作は、次のコードで実行されます。

int border_width_offset = border_width * width;
int border_height_offset = (height - border_width - 1) * width;

// Border pixels

Top_Border:for(int col = 0; col < border_width; col++){
  int offset = col * width;
  for(int row = 0; row < border_width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_width_offset + border_width];
  }
  for(int row = border_width; row < width - border_width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_width_offset + row];
  }
  for(int row = width - border_width; row < width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_width_offset + width - border_width - 1];
  }
}

Side_Border:for(int col = border_width; col < height - border_width; col++){
  int offset = col * width;
  for(int row = 0; row < border_width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[offset + border_width];
  }
  for(int row = width - border_width; row < width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[offset + width - border_width - 1];
  }
}

Bottom_Border:for(int col = height - border_width; col < height; col++){
  int offset = col * width;
  for(int row = 0; row < border_width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_height_offset + border_width];
  }
  for(int row = border_width; row < width - border_width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_height_offset + row];
  }
  for(int row = width - border_width; row < width; row++){
    int pixel = offset + row;
    dst[pixel] = dst[border_height_offset + width - border_width - 1];
  }
}

このコードには、データに繰り返しアクセスするという同じ問題があります。FPGA 外の dst 配列に格納されたデータは、入力データとして複数回読み出されることが可能になっている必要があります。最初のループでも、dst[border_width_offset + border_width] が複数回読み出されますが、border_width_offset および border_width の値は変更されません。

このコードは、読み出しと書き込みのどちらも非常にわかりやすいものです。SDSoC 環境でインプリメントすると約 120M クロック サイクルであり、CPU のパフォーマンスよりも少し長くなります。ただし、次のセクションで示すように最適なデータ アクセス パターンを使用すると、同じアルゴリズムをクロック サイクルごとに 1 ピクセルのレート (約 2M クロック サイクル) で FPGA にインプリメントできます。

このように、次のような不適切なデータ アクセス パターンを使用すると、パフォーマンスが低下し、FPGA インプリメンテーションのサイズが大きくなります。

  • データを繰り返し読み出すために複数回アクセスする。可能な場合は、ローカル ストレージを使用してください。
  • データに任意またはランダムにアクセスする。データをローカルに配列として格納する必要があり、リソースが多く必要になります。
  • 配列のデフォルト値を設定する。クロック サイクル数が多くなり、パフォーマンスが低下します。