前の記事では、メモリブロックの再利用順序がメモリ消費と最適化された機能に及ぼす影響を調査して、廃棄物を減らすことができました。ただし、もう1つのより深刻な問題は続きます。巨大なメモリブロックは、悪用される可能性のあるスペースの複数の小さなブロックを占める可能性があります。たとえば、メモリの大部分を割り当て、リリース後、2つの小さなチャンクを割り当てます。
<code class="language-c">void *ptr1 = abmalloc(128); void *ptr2 = abmalloc(8); abfree(ptr1); void *ptr3 = abmalloc(8); void *ptr4 = abmalloc(8);</code>
この時点で、128バイトのフリーブロックは8バイトのリクエストでは利用できず、その結果、ヒープを再度拡張する必要がある8バイトブロック割り当てが続き、メモリの利用が低くなります。
この問題を解決するための非常に効率的で複雑な方法は、「ビン」を使用することです。これは、サイズごとにグループ化されたチャンクのリストです。もう1つの簡単な解決策は、大きなチャンクを小さなチャンクに分割することです。この記事では、後者を採用しています。
コードリファクタリング
まず、コードをわずかにリファクトします。 header_new()
関数は、メモリの割り当てとブロックヘッダーの初期化に責任を負います。これは、コードの読みやすさとメンテナンスを助長しません。 2つの関数に分割します。
-
header_plug()
:前のブロックと次のブロックの間に初期化されたブロックを挿入します。 -
header_init()
:ブロックのメタデータ(サイズと可用性)を初期化します。
彼らは次のとおりです:
<code class="language-c">void header_init(header *header, size_t size, bool available) { header->size = size; header->available = available; } void header_plug(header *header, header *previous, header *next) { header->previous = previous; if (previous != NULL) { previous->next = header; } header->next = next; if (next != NULL) { next->previous = header; } }</code>
header_new()
関数は次のように変更されます。
<code class="language-c">header *header_new(header *previous, size_t size, bool available) { header *header = sbrk(sizeof(header) size); header_init(header, size, available); header_plug(header, previous, NULL); return header; }</code>
( last->previous->next = last;
abmalloc()
関数では、 header_plug()
がこのロジックの処理に責任を負うため、この行を削除できます。)
分割メモリブロック
次に、 header_split()
関数を実装します。ブロックヘッダーと必要な最小サイズが与えられると、元のブロックが十分に大きい場合は、次の2つの部分に分割します。
- 必要なサイズのブロック。
- 残りとその新しいブロック。
まず、ブロックが十分に大きいかどうかを確認してください。
<code class="language-c">header *header_split(header *header, size_t size) { size_t original_size = header->size; if (original_size >= size sizeof(header)) {</code>
十分に大きい場合は、ブロックを分割します。まず、現在のブロックのサイズを縮小します。
header->size = original_size - size - sizeof(header);
新しいブロックへのポインターを計算します。
header *new_header = (header 1) header->size; // Corrected pointer calculation
新しいブロックのヘッダーを初期化します。
header_init(new_header, size, true);
新しいブロックをリンクリストに接続します。
header_plug(new_header, header, header->next);
元のブロックが最後のブロックの場合、 last
ポインターを更新します。
if (header == last) { last = new_header; }
新しいブロックに戻る:
return new_header; } else { return header; } }
abmalloc()を更新します
最後に、 abmalloc()
関数を変更し、使用可能なブロックを見つけた後、 header_split()
を呼び出して分割しようとします。
<code class="language-c">if (header->available && (header->size >= size)) { header = header_split(header, size); header->available = false; return (void*)(header 1); // Cast to void* for correct return type }</code>
ブロックを分割できる場合、新しいブロックが返されます。それ以外の場合、元のブロックが返されます。
ブロックセグメンテーションに関するメモ
新しいブロックが元のブロックの最後に作成されることに注意する必要があります。最初に作成することもできますが、最後に新しいブロックを作成すると、新しいフリーブロックが古いブロックに近づき、次のabmalloc()
呼び出しの効率が向上します。
メモリの大きな塊を分割することは、メモリ管理の改善への一歩ですが、メモリの断片化の小さな塊にもつながる可能性があり、その結果、ヒープの拡大が必要な大きな要求が発生します。次の記事では、この問題を解決する方法について説明します。
以上がmalloc()とfree()を実装します - 大きなチャンクを分割しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

C#は、開発効率とタイプの安全性を必要とするプロジェクトに適していますが、Cは高性能とハードウェア制御を必要とするプロジェクトに適しています。 1)C#は、エンタープライズアプリケーションやWindows開発に適したGarbage CollectionとLINQを提供します。 2)Cは、その高性能と根本的な制御で知られており、ゲームやシステムのプログラミングで広く使用されています。

Cコードの最適化は、次の戦略を通じて実現できます。1。最適化のためにメモリを手動で管理する。 2。コンパイラ最適化ルールに準拠したコードを書きます。 3.適切なアルゴリズムとデータ構造を選択します。 4.インライン関数を使用して、コールオーバーヘッドを削減します。 5.コンパイル時に最適化するために、テンプレートメタプログラムを適用します。 6.不要なコピーを避け、移動セマンティクスと参照パラメーターを使用します。 7. constを正しく使用して、コンパイラの最適化を支援します。 8。std :: vectorなどの適切なデータ構造を選択します。

Cの揮発性キーワードは、変数の値がコード制御の外側に変更され、したがって最適化できないことをコンパイラに通知するために使用されます。 1)センサー状態などのハードウェアまたは割り込みサービスプログラムによって変更される可能性のある変数の読み取りによく使用されます。 2)揮発性は、マルチスレッドの安全性を保証することはできず、Mutexロックまたは原子操作を使用する必要があります。 3)揮発性を使用すると、パフォーマンスがわずかに減少する可能性がありますが、プログラムの正確性を確保します。

Cのスレッドパフォーマンスの測定は、標準ライブラリのタイミングツール、パフォーマンス分析ツール、およびカスタムタイマーを使用できます。 1.ライブラリを使用して、実行時間を測定します。 2。パフォーマンス分析にはGPROFを使用します。手順には、コンピレーション中に-pgオプションを追加し、プログラムを実行してGmon.outファイルを生成し、パフォーマンスレポートの生成が含まれます。 3. ValgrindのCallGrindモジュールを使用して、より詳細な分析を実行します。手順には、プログラムを実行してCallGrind.outファイルを生成し、Kcachegrindを使用して結果を表示することが含まれます。 4.カスタムタイマーは、特定のコードセグメントの実行時間を柔軟に測定できます。これらの方法は、スレッドのパフォーマンスを完全に理解し、コードを最適化するのに役立ちます。

CでChronoライブラリを使用すると、時間と時間の間隔をより正確に制御できます。このライブラリの魅力を探りましょう。 CのChronoライブラリは、時間と時間の間隔に対処するための最新の方法を提供する標準ライブラリの一部です。 Time.HとCtimeに苦しんでいるプログラマーにとって、Chronoは間違いなく恩恵です。コードの読みやすさと保守性を向上させるだけでなく、より高い精度と柔軟性も提供します。基本から始めましょう。 Chronoライブラリには、主に次の重要なコンポーネントが含まれています。STD:: Chrono :: System_Clock:現在の時間を取得するために使用されるシステムクロックを表します。 STD :: Chron

Cは、リアルタイムオペレーティングシステム(RTOS)プログラミングでうまく機能し、効率的な実行効率と正確な時間管理を提供します。 1)Cハードウェアリソースの直接的な動作と効率的なメモリ管理を通じて、RTOのニーズを満たします。 2)オブジェクト指向の機能を使用して、Cは柔軟なタスクスケジューリングシステムを設計できます。 3)Cは効率的な割り込み処理をサポートしますが、リアルタイムを確保するには、動的メモリの割り当てと例外処理を避ける必要があります。 4)テンプレートプログラミングとインライン関数は、パフォーマンスの最適化に役立ちます。 5)実際のアプリケーションでは、Cを使用して効率的なロギングシステムを実装できます。

CのABI互換性とは、異なるコンパイラまたはバージョンによって生成されたバイナリコードが再コンパイルなしで互換性があるかどうかを指します。 1。関数呼び出し規則、2。名前の変更、3。仮想関数テーブルレイアウト、4。構造とクラスのレイアウトが主な側面です。

CのDMAとは、直接メモリアクセステクノロジーであるDirectMemoryAccessを指し、ハードウェアデバイスがCPU介入なしでメモリに直接データを送信できるようにします。 1)DMA操作は、ハードウェアデバイスとドライバーに大きく依存しており、実装方法はシステムごとに異なります。 2)メモリへの直接アクセスは、セキュリティリスクをもたらす可能性があり、コードの正確性とセキュリティを確保する必要があります。 3)DMAはパフォーマンスを改善できますが、不適切な使用はシステムのパフォーマンスの低下につながる可能性があります。実践と学習を通じて、DMAを使用するスキルを習得し、高速データ送信やリアルタイム信号処理などのシナリオでその効果を最大化できます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

WebStorm Mac版
便利なJavaScript開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

Dreamweaver Mac版
ビジュアル Web 開発ツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ホットトピック









