2021年6月17日木曜日

Pimplはアンチパターンだと思います

はじめに

数年前は使うこともあったのですが, 現代にはふさわしくないと思い使わなくなりました.

利点と欠点, それについての考え

利点

  • includeを減らして, コンパイル時間の短縮
    • 2021年では, 計算機, コンパイラ, そしてリンカの性能が向上しました. これは使う理由にはなりません. 聞こえていますか?20年前から来たあなた
      • 時間は金で買うべきです, ビルドマシンぐらい金をかけましょう
    • 今のプロジェクトのビルドが遅い理由は, 次です. ビルドが遅すぎて, ビルドは一日一回, agileではなく, sluggishです, stupidプロジェクトでもいいです
      • Pimplを数多く使っているのに, includeが多い. コピペのせいもあるのですが
        • リファクタリングをしないので, コピペが修正されることは2度とない
      • inlineが多い
        • inlineを理解していない
        • コンパイラオプションで, できるだけinline展開するようにしている
        • inline展開で処理が速くなるとは限らない, これは今も昔も
      • コンパイラオプションで最大限の最適化を設定している
        • O2より上は速くなるかは環境依存, 遅くなることはよくある
          • 使用者が少ないので, 不具合も多くなる
        • コンパイラを理解していない
  • 実装の隠蔽
    • 例えば, JavaやC#で困ったことはありますか?
      • 自分の意に沿わないからといって, ヘッダを書き換えるようなエンジニア?をチームに置いておきますか? そちらの方が問題だと思います
    • インターフェイスを使って, FILEのようなことをすれば完全に隠蔽できるので, 使う理由にはなりません

欠点

  • メモリコストと実行速度に悪影響がある
    • 処理落ちがどうのなど, 言っていることとやっていることが異なる
  • 冗長
    • 処理を転送するだけの記述がコード量を増やす
    • コードを追うことに2倍のコストがかかる
    • たまにインターフェイスのメソッド名と, 実体のメソッド名が異なる
      • ガンジーでも助走付けて
  • ヘビークラスを作りやすい
    • これは当社比なのですが, 10年以上のエンジニア経験では, Pimplイディオムはくそでかクラスになりやすい傾向にあります
      • コンパイル時間の短縮という錦の旗, メモリコストと実行速度を考えると, Pimplイディオムがコンポジションに向いていないことが原因と思っています
    • コンポジションやアグリゲーションで, ソフトウェアを建築する, という考え方を持っている人には受け入れがたいです

まとめ

他人に強制するつもりはありませんが, 意味のないイディオムだと思います. 

2021年6月15日火曜日

BC5 圧縮テクスチャ

はじめに

プログラムから, テクスチャ圧縮がしたいです. BC1, BC3, BC6h BC7についてはispc texture compressionを使おうと思っていましたが, BC5がないのです.

https://software.intel.com/content/www/us/en/develop/articles/fast-ispc-texture-compressor-update.html

ガイドに仕様がちゃんと書いてあります. 簡単そうなので作ってしまいます.

https://docs.microsoft.com/en-gb/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc5

ファイルフォーマット

4x4のブロックごとに圧縮するブロック圧縮です. BC4はRだけの1チャネル, BC5はRGの2チャネルを扱います. 4x4x2 = 32 bytesを次の tablex2 = 16 bytesに圧縮します. BC5_UNORMとBC5_SNORMの2バリエーションです. 2つはシェーダでサンプルした場合, [0 1]の浮動小数点数になるか, [-1 1]の浮動小数点になるかが違います.

テーブルは, 4x4の最小値と最大値が先頭に2バイト, 次に3bits x 16のテーブルへのインデックスが並びます.

/*
MSB                   LSB
| red_0               | 1 byte minimum color
| red_1               | 1 byte maximum color
| red_h | red_g | red_f | red_e | red_d | red_c | red_b | red_a | 3 bits x 8
| red_p | red_o | red_n | red_m | red_l | red_k | red_j | red_i | 3 bits x 8
*/

テーブルは明示的に持たず最大値, 最小値から計算します. UNORMとSNORMで1箇所異なりますが, 圧縮するだけならばどちらでも同じなので統一します.

static constexpr u32 Shift = 20;
void createTable(s32 colors[8], s32 block[16])
{
    colors[0] = block[0];
    colors[1] = block[0];
    for(u32 i = 1; i < 16; ++i) {
        colors[0] = minimum(colors[0], block[i]);
        colors[1] = maximum(colors[1], block[i]);
    }
    colors[0] <<= Shift;
    colors[1] <<= Shift;

    if(colors[1] < colors[0]) {
        // 6 interpolated color values
        colors[2] = (6 * colors[0] + 1 * colors[1]) / 7; // bit code 010
        colors[3] = (5 * colors[0] + 2 * colors[1]) / 7; // bit code 011
        colors[4] = (4 * colors[0] + 3 * colors[1]) / 7; // bit code 100
        colors[5] = (3 * colors[0] + 4 * colors[1]) / 7; // bit code 101
        colors[6] = (2 * colors[0] + 5 * colors[1]) / 7; // bit code 110
        colors[7] = (1 * colors[0] + 6 * colors[1]) / 7; // bit code 111
    } else {
        // 4 interpolated color values
        colors[2] = (4 * colors[0] + 1 * colors[1]) / 5; // bit code 010
        colors[3] = (3 * colors[0] + 2 * colors[1]) / 5; // bit code 011
        colors[4] = (2 * colors[0] + 3 * colors[1]) / 5; // bit code 100
        colors[5] = (1 * colors[0] + 4 * colors[1]) / 5; // bit code 101
        colors[6] = 0;                                   // bit code 110
        colors[7] = 255<<Shift;                          // bit code 111
    }
}

ピクセル値に最も近いテーブルインデックスを検索して, 符号化します.

u64 findNearest(s32 colors[8], s32 x)
{
    u32 index = 0;
    s32 mind = absolute(colors[0] - x);
    for(u32 i = 1; i < 8; ++i) {
        s32 d = absolute(colors[i] - x);
        if(d < mind) {
            mind = d;
            index = i;
        }
    }
    return index;
}

まとめ

GPUOpen Compressonatorと結果が異なるため, もっといい方法がありそうです.

2021年6月10日木曜日

Windows 10 のシステムロケールの不具合

どの更新からか, Windows 10のシステムロケールに, "ベータ: ワールドワイド言語サポートでUnicode UTF-8を使用(U)"というチェックが追加された. デフォルトでONなのですが, これのせいで文字化けするアプリケーションが出てきた. 少しテストすればわかりそうなものですが.