2

ws2812 モジュールにコードを追加して、led 値を格納できる再利用可能なバッファを使用できるようにします。

現在のバージョンがあります。

2 つの問題があります。

最初に、「オブジェクト指向スタイル」のインターフェースが必要でした。だから私はした:

local buffer = ws2812.newBuffer(300);
for j = 0,299 do
   buffer:set(j, 255, 255, 255)
end
buffer:write(pin);

ここでの問題はbuffer:set、コストがかかる各ループ ターンで解決されることです (このループには ~20.2ms かかります)。

8       [2]     FORPREP         1 6     ; to 15
9       [3]     SELF            5 0 -7  ; "set"
10      [3]     MOVE            7 4
11      [3]     LOADK           8 -8    ; 255
12      [3]     LOADK           9 -8    ; 255
13      [3]     LOADK           10 -8   ; 255
14      [3]     CALL            5 6 1
15      [2]     FORLOOP         1 -7    ; to 9

「見栄えがよくない」この問題の回避策を見つけました。

local buffer = ws2812.newBuffer(300);
local set = getmetatable(buffer).set;
for j = 0,299 do
   set(buffer, j, 255, 255, 255)
end
buffer:write(pin);

これはうまく機能します (ループで 4.3 ミリ秒、4 倍以上高速) が、ハックに似ています。:/ buffer:set resolution を「キャッシュ」するより良い方法はありますか?

2 番目の質問、私の C コードでは、次を使用します。

ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");

これにより、バッファ ptr が返され、それが本当にws2812.buffer. しかし、この呼び出しは遅いです。私の ESP8266 では、約 50us です。呼び出しごとに (buffer:setたとえば、300 回) 実行すると、約 15 ミリ秒になります。

ユーザーデータを取得してそのタイプをチェックするより良い方法はありますか、それとも構造の先頭に「カナリア」を追加して独自のチェックを行う必要がありますか (50us と比較してほとんど「無料」になります...)?

4

1 に答える 1

3

ハックのように見えないようにするには、使用してみてください

local set = buffer.set

これは本質的に同じコードですが、メタテーブルはメタメソッドを通じて暗黙的に使用されるため、getmetatable はありません__index

私たちのプロジェクトでは、独自の実装を行いましたluaL_checkudata。同様に提案したように、1つのオプションは、型を保持するラッパーオブジェクトを使用することでした。すべてのユーザーデータはラッパーでラップされていると想定されていたため、それを使用してユーザーデータのタイプを取得および確認できました。しかし、ベンチマークは行われず、代わりにメタテーブルのテストが使用されました。

luaL_checkudataメタテーブルのテストは、メタテーブルを取得してテストするために多くの作業を行い、ラッピングを使用すると型に直接アクセスできるため、ラッピングよりも遅いと言えます。ただし、ベンチマークは確かにわかります。

于 2015-12-26T15:20:23.187 に答える