2

84 x 48 ピクセルの LCD 画面を制御するために、 C# ( Netduino Plus上で動作する.NET Micro Framework ) を使用しています。

1LCD 画面の各ピクセルには、 (ON) または0(OFF)の 2 つの状態があります。画面のピクセルを制御するには、 の配列を送信する必要があります504 bytes。ここで、それぞれbyteが 8 ピクセルの 1 列を表します (つまり、画面は 84 x 8 ピクセルの 6 行に「分割」されます)。

これは、次の例で最もよく示されています。

  • バイト00000001( 2^0) は、8 ピクセルの 1 列を表し、列の一番上の最初のピクセルがオン ( 1) です。

  • バイト00001001( 2^0 + 2^3) は、8 ピクセルの別の列を表し、列の上から 1 番目と 4 番目のピクセルがオンになっています。

これから、ビットごとのAND操作によって、特定の列のどのピクセルがオンまたはオフであるかが表示されることがわかります。たとえば、特定の 8 ピクセルの列の 4 番目のピクセルがオンになっているかどうかを確認するには、次のようにします。

00001001    AND
00001000
-----------------
00001000 > 0
∴ The 4th pixel is ON

(x,y)問題は、座標を使用して画面内の各ピクセルにアクセスできるようにする必要があることです。たとえば、ポイント(3,10)は、画面の左上隅のピクセルの右 4 と下 11 のピクセルを表します。同様に、ポイント(83,47)は画面の右下のピクセルを表します。

これを実現するために、次の C# コードを作成しました。

byte[] display = new byte[504];

// storing these means they don't need to be calculated every time:
byte[] base2 = { 1, 2, 4, 8, 16, 32, 64, 128 };

// Determine if the pixel is ON (true) or OFF (false)
public bool PixelState(Pixel px)
{
    return (display[GetColumn(px)] & base2[GetPxNum(px)]) > 0;
}

// Find the number of the pixel in its column of 8
private int GetPxNum(Pixel px)
{
    return px.y % 8;
}

// Find the index of the byte containing the bit representing the state of a pixel
private int GetColumn(Pixel px)
{
    return (px.y / 8 * 84) + px.x;
}

// Set a pixel's state
public void SetPixel(Pixel px, bool state)
{
    int col = GetColumn(px);
    int num = GetPxNum(px);

    if (state && !PixelState(px))
        display[col] += base2[num];
    else if (!state && PixelState(px))
        display[col] -= base2[num];
}

// Represents one (x,y) point
public struct Pixel
{
    public int x, y;

    public Pixel(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

これはマイクロコントローラー上で実行されるため、コードをできるだけ迅速かつ効率的にする必要があります。これらのメソッドは、LCD 画面のピクセルを更新するために立て続けに何度も呼び出される可能性があるため、これも必要です。

したがって、私の質問は、このコードをより高速かつ効率的にするにはどうすればよいですか? これについてもっと良い方法はありますか?

EDIT:いくつかの広範なテストの後、私はMath.Floor(または単に整数演算)で使用する必要があることに気づきましたGetColumn。コードを更新しました。

4

1 に答える 1

1

のこの小さなスニペットSetPixel:

if (state && !PixelState(px))
    display[col] += base2[num];
else if (!state && PixelState(px))
    display[col] -= base2[num];

次のものに置き換えることができます:

if (state)
    display[col] |= base2[num];
else
    display[col] &= (byte)~base2[num]; // You could precompute this inverse array too

利用可能なメモリが十分にある場合は、事前計算は問題ないかもしれませんが、真剣に、最近の uC は非常に多くの処理能力を備えています。ちょっとしたシフトや否定に本当に気がつくでしょうか?


(double)また、使用しないことに興味があるかもしれませんMath.ceiling()。マイクロコントローラーにはおそらく浮動小数点がサポートされていないため、エミュレートする必要があります (結果としてパフォーマンスが低下します。使用(float)すると改善されます (単精度エミュレーションの方が高速です)。これ:

return ( (px.y/8 + ((px.y%8)?1:0)) * 84 ) + px.x;

編集: netduino を詳しく見てみると、FPU がある可能性があります (ただし、データシートには表示されないため、おそらく表示されません...) 整数演算の代替手段は、おそらくさらに高速です :)


それが速いかどうかは、テストによってのみ保証できますが、コメントで述べたように、これは間違いなくボトルネックになり、時期尚早の最適化の別の犠牲者のように見えます.

ここでの最大のボトルネックはフレームワークです。

于 2012-04-06T04:54:20.640 に答える