目次

記憶の壁" >いわゆる順次一貫性は、キャッシュ一貫性とはまったく異なる概念を指しますが、どちらもプロセッサ開発の成果物です。コンパイラ テクノロジは進化し続けるため、コードを最適化するために特定の操作の順序が変更される場合があります。マルチイシューとアウトオブオーダー実行の概念は、プロセッサーに長い間存在していました。その結果、実際に実行される命令の順序は、プログラミング中のコードの実行順序とわずかに異なります。もちろん、これは単一のプロセッサの下では何も起こりません。結局のところ、自分のコードが通過しない限り、誰も気にしません。コンパイラとプロセッサは、自分のコードが発見されないようにしながら、実行順序を混乱させます。しかし、マルチプロセッサの場合はそうではなく、あるプロセッサで命令が完了する順序は、他のプロセッサで実行されるコードに大きな影響を与える可能性があります。したがって、あるプロセッサ上のスレッドの実行順序が、他のプロセッサ上のスレッドの観点から同じであることを保証する、逐次一貫性の概念があります。この問題を解決するには、プロセッサまたはコンパイラだけでは解決できず、ソフトウェアの介入が必要です。

記憶の壁

プロセッサ間の同期" >プロセッサ間の同期
内存屏障的实现" >内存屏障的实现
ホームページ システムチュートリアル Linux Linux カーネルのメモリバリアの詳細な説明

Linux カーネルのメモリバリアの詳細な説明

Feb 10, 2024 pm 03:00 PM
linux Linuxチュートリアル Linuxシステム Linuxコマンド シェルスクリプト 埋め込みLinux Linux を始める Linux学習

######序文######

以前、逐次一貫性とキャッシュ一貫性に関するディスカッション記事を読み、これら 2 つの概念の違いと関連性をより明確に理解しました。 Linux カーネルには、多くの同期およびバリア メカニズムが存在します。ここでは、それらについて要約したいと思います。

キャッシュの一貫性Linux カーネルのメモリバリアの詳細な説明

以前は、Linux の多くのメカニズムはキャッシュの一貫性を確保するためのものだと常々思っていましたが、実際には、キャッシュの一貫性のほとんどはハードウェア メカニズムによって実現されています。ロック接頭辞を持つ命令を使用する場合にのみ、キャッシュに関係します (これは厳密ではありませんが、現在の観点から見ると、ほとんどの場合に当てはまります)。ほとんどの場合、私たちは逐次一貫性を確保したいと考えています。 キャッシュの一貫性とは、マルチプロセッサ システムでは、各 CPU が独自の L1 キャッシュを持つことを意味します。同じメモリの内容が異なる CPU の L1 キャッシュにキャッシュされる可能性があるため、CPU がキャッシュされた内容を変更する場合、このデータを読み取るときに別の CPU も最新の内容を読み取ることができるようにする必要があります。ただし、この複雑な作業はハードウェアによって完全に実行されるので、心配しないでください。MESI プロトコルを実装することで、ハードウェアはキャッシュ コヒーレンシ作業を簡単に完了できます。複数のCPUが同時に書き込みをしても問題ありません。 CPU は、自身のキャッシュ、他の CPU のキャッシュ、メモリのいずれに存在しても、常に最新のデータを読み取ることができ、これがキャッシュの一貫性の仕組みです。

シーケンシャル一貫性

いわゆる順次一貫性は、キャッシュ一貫性とはまったく異なる概念を指しますが、どちらもプロセッサ開発の成果物です。コンパイラ テクノロジは進化し続けるため、コードを最適化するために特定の操作の順序が変更される場合があります。マルチイシューとアウトオブオーダー実行の概念は、プロセッサーに長い間存在していました。その結果、実際に実行される命令の順序は、プログラミング中のコードの実行順序とわずかに異なります。もちろん、これは単一のプロセッサの下では何も起こりません。結局のところ、自分のコードが通過しない限り、誰も気にしません。コンパイラとプロセッサは、自分のコードが発見されないようにしながら、実行順序を混乱させます。しかし、マルチプロセッサの場合はそうではなく、あるプロセッサで命令が完了する順序は、他のプロセッサで実行されるコードに大きな影響を与える可能性があります。したがって、あるプロセッサ上のスレッドの実行順序が、他のプロセッサ上のスレッドの観点から同じであることを保証する、逐次一貫性の概念があります。この問題を解決するには、プロセッサまたはコンパイラだけでは解決できず、ソフトウェアの介入が必要です。

記憶の壁

ソフトウェア介入の方法も非常に簡単で、メモリバリアを挿入するだけです。実際、メモリバリアという用語はプロセッサ開発者によって作られたものであり、私たちにとっては理解しにくいものです。メモリバリアにより、キャッシュの一貫性が簡単に失われる可能性があり、変更されたキャッシュを他の CPU が参照できるようにすることができるかどうかすら疑問になりますが、そう考えるのは間違いです。いわゆるメモリ バリアは、プロセッサの観点から見ると、読み取りおよび書き込み操作をシリアル化するために使用され、ソフトウェアの観点から見ると、逐次一貫性の問題を解決するために使用されます。コンパイラは、コードの実行順序を乱したくないのでしょうか? プロセッサは、コードを順序どおりに実行したくないのでしょうか? メモリ バリアを挿入することは、コンパイラに命令の前後の順序を変更するように指示することと同じです。バリアは元に戻すことはできません。プロセッサに対して、バリアの前の命令のみを待機できるように指示します。命令が実行された後、バリアの後ろの命令の実行を開始できます。もちろん、メモリの障壁によってコンパイラの混乱を防ぐことはできますが、プロセッサにはまだ解決策があります。プロセッサには、複数発行、アウトオブオーダー実行、およびシーケンシャル完了という概念はありませんか? メモリ バリア中は、前の命令の読み取りおよび書き込み操作が、プロセッサが実行される前に完了していることを確認するだけで十分です。次の命令の読み取りおよび書き込み操作が完了します。したがって、メモリ バリアには、読み取りバリア、書き込みバリア、読み取り/書き込みバリアの 3 種類があります。たとえば、x86 より前では、書き込み操作は順序どおりに完了することが保証されていたため、書き込みバリアは必要ありませんでしたが、一部の ia32 プロセッサでは、書き込み操作が順序どおりに完了しないため、書き込みバリアも必要になりました。
実際、特殊な読み書きバリア命令に加えて、ロック プレフィックスを持つ命令など、読み書きバリア機能を使用して実行される命令が多数あります。特殊な読み取りおよび書き込みバリア命令が登場するまで、Linux はロックに依存して生き残っていました。
読み取りおよび書き込みバリアをどこに挿入するかについては、ソフトウェアのニーズによって異なります。読み取り/書き込みバリアは逐次一貫性を完全に達成することはできませんが、マルチプロセッサ上のスレッドは実行順序を常に監視しているわけではありません。監視するときに逐次一貫性が遵守されていると判断される限り、スレッドは実行順序を監視します。実行によってコードに予期しない状況が発生することはありません。いわゆる予期せぬ状況、たとえば、スレッドが最初に変数 a に値を割り当て、次に変数 b に値を割り当てます。その結果、他のプロセッサで実行されているスレッドが調べて、b に値が割り当てられていることがわかります。しかし、 a には値が割り当てられていません (注: この不一致はキャッシュの不一致が原因ではなく、プロセッサの書き込み操作が完了する順序の不一致によって引き起こされます)。この場合、割り当てと割り当ての間に書き込みバリアを追加する必要があります。 a と b の代入。

プロセッサ間の同期

SMP を使用すると、スレッドは複数のプロセッサ上で同時に実行を開始します。スレッドである限り、通信と同期の要件が存在します。幸いなことに、SMP システムは共有メモリを使用するため、すべてのプロセッサが同じメモリ内容を認識します。独立した L1 キャッシュがありますが、キャッシュの整合性処理は依然としてハードウェアによって処理されます。異なるプロセッサ上のスレッドが同じデータにアクセスしたい場合は、クリティカル セクションと同期が必要です。同期は何に依存しますか?以前の UP システムでは、上部ではセマフォに依存し、下部では割り込みと読み取り、変更、書き込み命令をオフにしていました。現在、SMP システムでは割り込みをオフにする機能は廃止されており、同じプロセッサ上のスレッドを同期する必要があることに変わりはありませんが、それだけに頼るだけでは十分ではなくなりました。読み取り変更書き込み命令?もうない。命令内の読み取り操作が完了し、書き込み操作が実行されていない場合、別のプロセッサーが読み取り操作または書き込み操作を実行する可能性があります。キャッシュ コヒーレンス プロトコルは進歩していますが、どの命令がこの読み取り操作を発行したかを予測できるほどまだ進歩していません。そこで、x86 はロック プレフィックスを伴う命令を発明しました。この命令が実行されると、命令内の読み取りおよび書き込みアドレスを含むすべてのキャッシュ ラインが無効になり、メモリ バスがロックされます。このように、他のプロセッサが同じアドレスまたは同じキャッシュ ライン上のアドレスを読み書きしたい場合、キャッシュから実行することも (キャッシュ内の関連するラインの有効期限が切れている)、キャッシュから実行することもできません。メモリ バス (メモリ バス全体に障害が発生しました)、ロックされています)、最終的にアトミック実行の目標を達成します。もちろん、P6 プロセッサ以降では、ロック プレフィックス命令でアクセスするアドレスがすでにキャッシュ内にある場合、メモリ バスをロックする必要はなく、アトミック操作を完了できます (これはおそらく、マルチプロセッサの内部共通機能の追加) L2キャッシュのため)

メモリ バスがロックされるため、未完了の読み取りおよび書き込み操作は、ロック プレフィックスが付いた命令が実行される前に完了し、メモリ バリアとしても機能します。
現在、マルチプロセッサ間のスレッドの同期には、上部でスピン ロックが使用され、下部でロック プレフィックスを使用した読み取り、変更、書き込み命令が使用されます。もちろん、実際の同期には、プロセッサのタスク スケジューリングの無効化、タスクオフ割り込みの追加、外部セマフォの追加も含まれます。 Linux でのこの種のスピン ロックの実装は 4 世代にわたる開発を経て、より効率的かつ強力になりました。

内存屏障的实现

\#ifdef CONFIG_SMP  
\#define smp_mb()  mb()  
\#define smp_rmb()  rmb()  
\#define smp_wmb()  wmb()  
\#else  
\#define smp_mb()  barrier()  
\#define smp_rmb()  barrier()  
\#define smp_wmb()  barrier()  
\#endif 
ログイン後にコピー

CONFIG_SMP就是用来支持多处理器的。如果是UP(uniprocessor)系统,就会翻译成barrier()。

#define barrier() asm volatile(“”: : :”memory”)
barrier()的作用,就是告诉编译器,内存的变量值都改变了,之前存在寄存器里的变量副本无效,要访问变量还需再访问内存。这样做足以满足UP中所有的内存屏障。

\#ifdef CONFIG_X86_32  
/* 
 \* Some non-Intel clones support out of order store. wmb() ceases to be a 
 \* nop for these. 
 */  
\#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)  
\#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)  
\#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)  
\#else  
\#define mb()  asm volatile("mfence":::"memory")  
\#define rmb()  asm volatile("lfence":::"memory")  
\#define wmb()  asm volatile("sfence" ::: "memory")  
\#endif 
ログイン後にコピー

如果是SMP系统,内存屏障就会翻译成对应的mb()、rmb()和wmb()。这里CONFIG_X86_32的意思是说这是一个32位x86系统,否则就是64位的x86系统。现在的linux内核将32位x86和64位x86融合在同一个x86目录,所以需要增加这个配置选项。

可以看到,如果是64位x86,肯定有mfence、lfence和sfence三条指令,而32位的x86系统则不一定,所以需要进一步查看cpu是否支持这三条新的指令,不行则用加锁的方式来增加内存屏障。

SFENCE,LFENCE,MFENCE指令提供了高效的方式来保证读写内存的排序,这种操作发生在产生弱排序数据的程序和读取这个数据的程序之间。 
  SFENCE——串行化发生在SFENCE指令之前的写操作但是不影响读操作。 
  LFENCE——串行化发生在SFENCE指令之前的读操作但是不影响写操作。 
  MFENCE——串行化发生在MFENCE指令之前的读写操作。 
sfence:在sfence指令前的写操作当必须在sfence指令后的写操作前完成。 
lfence:在lfence指令前的读操作当必须在lfence指令后的读操作前完成。 
mfence:在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成。
ログイン後にコピー

至于带lock的内存操作,会在锁内存总线之前,就把之前的读写操作结束,功能相当于mfence,当然执行效率上要差一些。

说起来,现在写点底层代码真不容易,既要注意SMP问题,又要注意cpu乱序读写问题,还要注意cache问题,还有设备DMA问题,等等。

多处理器间同步的实现
多处理器间同步所使用的自旋锁实现,已经有专门的文章介绍

以上がLinux カーネルのメモリバリアの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Android TV Box が非公式の Ubuntu 24.04 アップグレードを取得 Android TV Box が非公式の Ubuntu 24.04 アップグレードを取得 Sep 05, 2024 am 06:33 AM

多くのユーザーにとって、Android TV ボックスをハッキングするのは気が遠くなるように思えます。しかし、開発者の Murray R. Van Luyn は、Broadcom チップが不足する中、Raspberry Pi に代わる適切な代替品を探すという課題に直面しました。アルムビアとの共同作業

Deepseek Webバージョンの入り口Deepseek公式ウェブサイトの入り口 Deepseek Webバージョンの入り口Deepseek公式ウェブサイトの入り口 Feb 19, 2025 pm 04:54 PM

DeepSeekは、Webバージョンと公式Webサイトの2つのアクセス方法を提供する強力なインテリジェント検索および分析ツールです。 Webバージョンは便利で効率的であり、公式ウェブサイトは包括的な製品情報、ダウンロードリソース、サポートサービスを提供できます。個人であろうと企業ユーザーであろうと、DeepSeekを通じて大規模なデータを簡単に取得および分析して、仕事の効率を向上させ、意思決定を支援し、イノベーションを促進することができます。

DeepSeekをインストールする方法 DeepSeekをインストールする方法 Feb 19, 2025 pm 05:48 PM

DeepSeekをインストールするには、Dockerコンテナ(最も便利な場合は、互換性について心配する必要はありません)を使用して、事前コンパイルパッケージ(Windowsユーザー向け)を使用してソースからコンパイル(経験豊富な開発者向け)を含む多くの方法があります。公式文書は慎重に文書化され、不必要なトラブルを避けるために完全に準備します。

BitPie Bitpie ウォレット アプリのダウンロード アドレス BitPie Bitpie ウォレット アプリのダウンロード アドレス Sep 10, 2024 pm 12:10 PM

BitPie Bitpie ウォレット アプリをダウンロードするにはどうすればよいですか?手順は次のとおりです。 AppStore (Apple デバイス) または Google Play ストア (Android デバイス) で「BitPie Bitpie Wallet」を検索します。 「入手」または「インストール」ボタンをクリックしてアプリをダウンロードします。コンピューター版の場合は、BitPie ウォレットの公式 Web サイトにアクセスし、対応するソフトウェア パッケージをダウンロードしてください。

Bitget公式ウェブサイトのインストール(2025初心者ガイド) Bitget公式ウェブサイトのインストール(2025初心者ガイド) Feb 21, 2025 pm 08:42 PM

Bitgetは、スポット取引、契約取引、デリバティブなど、さまざまな取引サービスを提供する暗号通貨交換です。 2018年に設立されたこのExchangeは、シンガポールに本社を置き、安全で信頼性の高い取引プラットフォームをユーザーに提供することに取り組んでいます。 Bitgetは、BTC/USDT、ETH/USDT、XRP/USDTなど、さまざまな取引ペアを提供しています。さらに、この取引所はセキュリティと流動性について評判があり、プレミアム注文タイプ、レバレッジド取引、24時間年中無休のカスタマーサポートなど、さまざまな機能を提供します。

Zabbix 3.4 ソースコードコンパイルのインストール Zabbix 3.4 ソースコードコンパイルのインストール Sep 04, 2024 am 07:32 AM

1. インストール環境 (Hyper-V 仮想マシン): $hostnamectlStatichostname:localhost.localdomainIconname:computer-vmChassis:vmMachineID:renwoles1d8743989a40cb81db696400BootID:renwoles272f4aa59935dcdd0d456501Virtualization:microsoftOperatingSystem:CentOS Linux7(Core)CPEOSName: CP:

OUYI OKXインストールパッケージが直接含まれています OUYI OKXインストールパッケージが直接含まれています Feb 21, 2025 pm 08:00 PM

世界をリードするデジタル資産交換であるOuyi Okxは、安全で便利な取引体験を提供するために、公式のインストールパッケージを開始しました。 OUYIのOKXインストールパッケージは、ブラウザに直接インストールでき、ユーザー向けの安定した効率的な取引プラットフォームを作成できます。インストールプロセスは、簡単で理解しやすいです。

gate.ioインストールパッケージを無料で入手してください gate.ioインストールパッケージを無料で入手してください Feb 21, 2025 pm 08:21 PM

Gate.ioは、インストールパッケージをダウンロードしてデバイスにインストールすることで使用できる人気のある暗号通貨交換です。インストールパッケージを取得する手順は次のとおりです。Gate.ioの公式Webサイトにアクセスし、「ダウンロード」をクリックし、対応するオペレーティングシステム(Windows、Mac、またはLinux)を選択し、インストールパッケージをコンピューターにダウンロードします。スムーズなインストールを確保するために、インストール中に一時的にウイルス対策ソフトウェアまたはファイアウォールを一時的に無効にすることをお勧めします。完了後、ユーザーはGATE.IOアカウントを作成して使用を開始する必要があります。

See all articles