Arudinoで、RAMの残りを求める関数として、以下のサイトにavailableMemoryというものが紹介されている。
https://playground.arduino.cc/Code/AvailableMemory/
これは、mallocの戻り値がNULLでなくなる=確保できるまで1バイトずつサイズを小さくして試すという仕組み。 原理が単純で分かりやすいのだが、ESP-WROOM-32などRAM容量の大きなものに対してそのまま使うと、非常に動作が遅い。また、残り容量次第で計算時間が大きく変化する。
そこで、高速化をしてみた。
mallocの戻り値がNULLでなくなるごとにstepという変数の値を半分に小さくしていく。つまり、バイナリサーチだ。size=1MB、step=128kBであれば、最悪でも40回程度で探索が終わってくれる。運が良ければ16回。
size_t availableMemory() { size_t size = 1024 * 1024; // 最大サイズ size_t step = 128 * 1024; // 探索ステップ while (true) { byte *buf; while ((buf = (byte *) malloc(size)) == NULL) { size -= step; } free(buf); //Serial.printf("step=%d, size=%d\n", step, size); step /= 2; if (step == 0) break; size += step * 2; } return size; }
実際、使ってみると、非常に素早く終了する。デバッグ用に、プログラムの各所に入れても、それほど動作に影響を与えないだろう。