2

私が取り組んでいる組み込みデバイスでは、起動時間が重要な問題です。アプリケーション全体は、一連のライブラリを使用するいくつかの実行可能ファイルで構成されています。FLASHメモリのスペースが限られているため、共有ライブラリを使用したいと思います。

コンパイルして共有ライブラリとリンクすると、アプリケーションは通常どおり動作し、フラッシュメモリの量は予想どおりに減少します。静的ライブラリにリンクされているバージョンとの違いは、アプリケーションの起動時間が約20秒長く、理由がわからないことです。

このアプリケーションは、Linux 2.6.17 OS、16 MB FLASH(JFFSファイルシステム)、および32MBRAMを搭載した180MHzのARM9CPUで実行されます。

4

6 に答える 6

7

Bacause共有ライブラリは、実行時に、通常はdlopen()などによってリンクする必要があります。静的ライブラリにはそのような手順はありません。

編集:もう少し詳細。dlopenは次のタスクを実行する必要があります。

  • 共有ライブラリを探す
  • メモリにロードします
  • すべての依存関係(およびそれらの依存関係....)を再帰的にロードします
  • すべてのシンボルを解決する

これを実行するには、かなり多くのIO操作が必要です。

静的にリンクされたプログラムでは、上記のすべては実行時ではなくコンパイル時に実行されます。したがって、静的にリンクされたプログラムをロードする方がはるかに高速です。

あなたの場合、コードを実行しなければならないハードウェアが比較的遅いため、違いは誇張されています。

于 2009-09-11T12:58:01.813 に答える
4

これは、速度とスペースの古典的なトレードオフの良い例です。

すべての実行可能ファイルを静的にリンクして、高速にすることができますが、より多くのスペースが必要になります

また

スペースを節約するだけでなく、ロードにかかる時間を長くする共有ライブラリを作成できます。

だからあなたが犠牲にしたいものを決めなさい。

この違いには多くの要因(OS、コンパイラなど)がありますが、理由の良いリストはここにあります。基本的に共有ライブラリはスペース上の理由で作成されており、それらを機能させるために必要な「魔法」の多くはパフォーマンスに影響を与えます。

(歴史的なメモとして、Linux / Unix上の元のNetscapeナビゲーターは、静的にリンクされた大きなファット実行可能ファイルでした)。

于 2009-09-11T13:08:33.043 に答える
2

これは、同様の問題を抱えている他の人を助けるかもしれません:

私の場合、起動に時間がかかったのは、GCCのデフォルト設定がライブラリ内のすべてのシンボルをエクスポートするためです。大きな改善点は、コンパイラ設定「-fvisibility=hidden」を設定することです。

libがエクスポートする必要のあるすべてのシンボルは、ステートメントで拡張する必要があります

__attribute__ ((visibility("default")))

gccwikiと共有ライブラリの書き方
に関する非常にすばらしい記事を参照してください。

于 2009-10-22T15:16:59.473 に答える
1

さて、共有ライブラリの使用には速度に関する不利な点があることを学びました。ダイナミックリンクとロードエンライトについてのこの記事を見つけました。読み込みプロセスは、私が予想していたよりもはるかに長いようです。

于 2009-09-11T13:27:37.220 に答える
0

興味深い..通常、共有ライブラリの読み込み時間は、静的にリンクされているファットアプリからは気づかれません。したがって、システムがフラッシュメモリからライブラリをロードするのが非常に遅いか、ロードされているライブラリが何らかの方法でチェックされていると推測できます(たとえば、.NETアプリはロードされたすべてのdllに対してチェックサムを実行し、起動時間を大幅に短縮しますある場合)。共有ライブラリが必要に応じてロードされ、後でアンロードされている可能性があります。これは、構成の問題を示している可能性があります。

申し訳ありませんが、理由はわかりませんが、ARMデバイス/OSに問題があると思います。スタートアップコードをインストルメント化するか、最も一般的に使用されるライブラリの1つと静的にリンクして、それが大きな違いを生むかどうかを確認してみましたか。また、共有ライブラリをアプリと同じディレクトリに配置して、FSでライブラリを検索するのにかかる時間を短縮します。

于 2009-09-11T13:21:36.643 に答える
0

私には明らかなオプションの1つは、複数のプログラムをすべて1つのバイナリに静的にリンクすることです。そうすれば、可能な限り多くのコードを共有し続けることができますが(おそらく以前よりも多く)、ダイナミックリンカーのオーバーヘッドを回避し、システム上にダイナミックリンカーを配置するスペースを節約できます。

複数の実行可能ファイルを同じものに結合するのは非常に簡単です。通常は、argvを調べて、それに基づいて呼び出すルーチンを決定します。

于 2009-09-11T21:15:12.983 に答える