関連する本の推奨事項
読書の原則:不求甚解,观其大略
- コーディング:コンピュータソフトウェアとハードウェアの背後に隠された言語
- 「コンピュータシステムを理解する」
- データ構造とアルゴリズム
- 「Javaのデータ構造とアルゴリズム」「アルゴリズム」
- 「アルゴリズム入門」「TheArtofComputerProgramming」
- オペレーティングシステム:Linuxカーネルのソースコード分析Linuxカーネルの設計と実装30日間の自作オペレーティングシステム
- ネットワーク:元のバージョンを読むには、Mechanicの「TCP/IP詳細説明」第1巻をお勧めします
- コンパイルの原則:メカニカルドラゴンブックのプログラミング言語の実装モード
- データベース:SQLiteソースDerby
CPUの基本
CPUの製造工程
エッセンス:砂の山+銅の山+接着剤の山+特定の金属の添加+特別なプロセス
砂の脱酸->石英->シリカ->精製->シリコンインゴット->切断->ウェーハ->フォトレジストの塗布->リソグラフィー->エッチング->フォトレジストの除去->メッキ->研磨->銅層->テスト->スライス->パッケージ
CPUの内部:シリコン->特殊要素の追加->P半導体N半導体->PN接合->ダイオード->電界効果トランジスタ->ロジックスイッチ
基本的な論理回路:ANDゲートORゲートNOTゲートNORゲート(排他的論理和)加算器アキュムレータラッチ…
手動計算を実現(毎回メモリ命令を読み取る、(高電力低電力))
おすすめの本:コーディングの第17章
CPU動作の場合、それは高周波、低周波を介して->ロジックに変換され、2進数です:0、1->どのピンをオンまたはオフにする必要があるかをコンピューターに通知します
手動入力:紙テープコンピュータ
ニーモニック:01000010-> mov sub .. ..
高水準言語->コンパイラ->機械語
CPUの原理
コンピュータが解決する必要がある最も基本的な問題:数字を表現する方法
アセンブリ言語の実行プロセス
アセンブリの本質:機械語のニーモニック、実際には機械語です:movsubaddはバイナリデータを表します
プロセス:コンピュータの電源をオンにする-> CPUがメモリ内のプログラムを読み取る(電気信号入力)->クロックジェネレータが連続的にオンとオフを切り替える-> CPUをプッシュして段階的に実行する(実行されるステップ数はクロックサイクルによって異なります)命令で必要)->計算完了->ライトバック(電気信号)->グラフィックカード出力(soutまたはグラフィック)への書き込み
量子コンピューター(ただ理解する)
キュービット
コンピューターの構成
CPU和内存,是计算机的核心
CPUの基本構成
PC->プログラムカウンタープログラムカウンター(現在の命令アドレスを記録します)
レジスタ->レジスタ:CPU計算に必要なデータを一時的に保存します
ALU->算術論理演算装置
CU->コントロールユニットコントロールユニット割り込み信号制御
MMU->メモリ管理ユニットメモリ管理ユニット–ハードウェア+OSの実装
ハイパースレッディング:1つのALUは、複数のPCに対応します|
図に示すように、いわゆる4つのコアと8つのスレッドを登録します。
メモリ階層
なぜキャッシュがあるのですか?
異なるレジスタとメインメモリへのCPUの速度が同じではないため
キャッシュの物理構造
按块读取
キャッシングの最も基本的な原則:プログラムの局所性の原則。これにより、効率が向上
し、バスCPUピンが一度により多くのデータを読み取る能力を十分に発揮できます。
キャッシュ
データの整合性を確保するために:キャッシュ動作の単位で、4つのキャッシュライン状態
整合性プロトコルが定義されています
キャッシュラインサイズ
キャッシュライン:現在、L3キャッシュは業界に最適です。
キャッシュラインが大きいほど、ローカルスペースの効率は高くなりますが、読み取り時間は遅くなります
。
キャッシュ現在主に使用されている値:64バイト
揮発性の同じキャッシュラインの1億の割り当て実行効率により、スレッド間の可視性が保証されます
package com.mashibing.juc.c_028_FalseSharing;
public class T03_CacheLinePadding {
public static volatile long[] arr = new long[2];
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(()->{
for (long i = 0; i < 10000_0000L; i++) {
arr[0] = i;
}
});
Thread t2 = new Thread(()->{
for (long i = 0; i < 10000_0000L; i++) {
arr[1] = i;
}
});
final long start = System.nanoTime();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println((System.nanoTime() - start)/100_0000);
}
}
さまざまなキャッシュラインの1億の割り当て実行効率
package com.mashibing.juc.c_028_FalseSharing;
public class T04_CacheLinePadding {
public static volatile long[] arr = new long[16];
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(()->{
for (long i = 0; i < 10000_0000L; i++) {
arr[0] = i;
}
});
Thread t2 = new Thread(()->{
for (long i = 0; i < 10000_0000L; i++) {
arr[8] = i;
}
});
final long start = System.nanoTime();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println((System.nanoTime() - start)/100_0000);
}
}
結果は、異なるキャッシュラインで実行がより高速であることを明確に示しています
したがって、プログラミングパターンが生まれました-キャッシュラインアラインメント
キャッシュラインアラインメント:一部の特に機密性の高い数値では、スレッド競合アクセスが高くなります。偽共有が発生しないようにするために、キャッシュラインアライメントプログラミングを使用できます。
たとえば、独立したキャッシュラインを確保するために、ディスラプターの前後に7つの長いデータが入力されます
。JDK7では、多くの場合、効率を向上させるために長いパディングが使用されます。
JDK8、追加された@Contendedアノテーション(実験的)追加する必要があります:JVM -XX:-RestrictContended
package com.mashibing.juc.c_028_FalseSharing;
import sun.misc.Contended;
/**
* T05_Contended
* Description
*
* @date 2020/5/26 - 23:38
*/
public class T05_Contended {
@Contended
volatile long x;
@Contended
volatile long y;
public static void main(String[] args) throws InterruptedException {
T05_Contended t = new T05_Contended();
Thread t1 = new Thread(()->{
for (long i=0;i<1_0000_0000L;i++){
t.x=i;
}
});
Thread t2 = new Thread(()->{
for (long i=0;i<1_0000_0000L;i++){
t.y=i;
}
});
final long start = System.nanoTime();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println((System.nanoTime() - start)/100_0000);
}
}