メモリに非常に敏感な組み込みアプリケーションで、newlib 関数のいくつかが多くのスタック スペースを使用していることに気付きました。newlib のソース コード、特にこの場合は memmem.c を見ると、PREFER_SIZE_OVER_SPEED と __OPTIMIZE_SIZE__ の 2 つの定義に気付きました。これにより、メモリ使用量を大幅に削減できます。私が理解している限り、これらは「サイズに最適化された」ライブラリを利用するために newlib をコンパイルするときに定義する必要があります。私はcortex-M3マイクロコントローラーを使用しているため、「サイズに最適化された」newlibを使用するARMツールチェーンがあるか、それを使用するためのオプションを提供するか、自分で構築しようとする必要があります。さらに、newlib をビルドするときに、GCC もビルドする必要がありますか、それとも単にライブラリをビルドして現在のツールチェーンで使用できますか。現在、提供されているツールチェーンで CoIDE を使用しています。
2 に答える
コンパイラではなく、ライブラリのみをビルドする必要があります。
ただし、サイズの最適化は、スタック サイズではなくコード サイズに関連していると思います。スタック サイズは、auto 変数のサイズまたは数が削減された場合にのみ削減され、一般に、アルゴリズムの最適化ではなく、必要な機能によって決定されます。
多くの場合、大量のデータの移動を含む高レベルの操作は、より多くのメモリを使用することで高速化できますが、C 標準ライブラリのレベルではそのような機会は最小限であると言えます。そのため、「速度よりもサイズを優先します」データメモリの使用量ではなく、コードサイズがすべてです。
標準機能ではないmemmemを使用しています。これはglibcのGNU拡張機能です。実際に実行しているコードはstr-two-way.hにあります。私はそれを研究しませんでしたが、それはボイヤー-ムーアのような劣線形文字列検索であり、ボイヤー-ムーアに関するウィキペディアの記事を示しています。もちろん、これにはいくらかのメモリコストがかかります。
それは標準関数でさえないので、あなたがそれを気に入らなければ、newlibの実装を使う理由はありません。独自の部分文字列検索機能を使用するだけです。二次時間で十分であることがわかっている場合は、独自のコードでmemmem.cの5行ループを使用してください。memcmpがアラインされていないロードに対して正しいことを実行することを確認することをお勧めします(アーキテクチャがそれらをサポートしている場合)。そうでない場合は、手動のネストされたループの方がmemcmpを呼び出すよりも高速である可能性があります。