好きこそものの上手なるyukichi

プログラミング学習の備忘録。万歳車輪の再発明。

【試して理解】Linuxのしくみ 読んだメモ

忘れないようメモ📝LinuxのシステムをC言語でプログラム書いて色々覗いてみようという本。 個人的に見よう見まねでCを書けて楽しかったし、メモリ操作とかあってハードウェアに近い言語なんだなって体感した。 Cをもう少しやってみたいので、東大でCの基礎を学ぶ講義が公表されているのでこれをやってみようと思います。

1

2. ユーザーモード

3. プロセス管理

  • プロセス生成は2種類
    • 同じプログラムの処理を複数プロセスに分けて処理
      • fork()(内部的にはclone()):発行したプロセスを元に、新たにプロセスを1つ生成。
    • 全く別のプログラムを生成 ‐ プロセス数が増えるのではなく、あるプロセスを他のプロセスで上書きする
      • execve():
    • プログラム実行の流れ:プログラムファイルの情報(補助的情報・コード領域・データ領域)に基づいてメモリ上にマップされる → エントリポイントからプログラムを実行する
    • プロセス終了時は_exit()関数を使用。直接呼び出すことは少なく、Cならexit()呼び出しで終了

4. システムスケジューラ

  • 論理CPU上である瞬間に動作できるプロセスは1つのみ
  • 複数プロセス実行中の場合、途中でプロセスを切り替えている→切り替えをコンテキストスイッチという
  • プロセスのスリープ状態時はCPUはアイドリング状態(使っていない)
  • レイテンシ:処理の終了までの所要時間
  • スループット:単位時間当たりの総仕事量
  • 論理CPU0と、論理CPU/2の番号のものは独立している
  • プロセス数を論理CPU数より多くしても、スループットは上がらない
  • nice(): 特定のプロセスに優先度を設定する。-19(高い)~20(低い)。優先度を上げられるのはrootのみ

5. メモリ管理

  • メモリ使用量が増えて身動きが取れない事:OOM(out of memory), メモリ管理システムはこの時適当なプロセスをkillしてメモリを開放する機能がある。
  • sysctlのvm.panic_on_oomが0→デフォルト、killer発動, 1->OOM時にシステム強制終了
  • プログラムはメモリが断片化していると、使用できないこともある
  • 仮想記憶:物理メモリにプロセスから直接アクセスするのではなく、仮想アドレスを用いて間接的にアクセスすること。仮想アドレス=プロセスから見えるメモリのアドレス。プロセスから物理アドレスに直接アクセスする方法はなし。
  • 仮想アドレス≠物理アドレス
  • 仮想アドレスと物理 -アドレスの対応表をページテーブルという。サイズは4KB(x86_64アーキテクチャ).
  • メモリ割り当て方法
    1. 必要な領域を物理メモリに割り当て、必要なデータをそこにコピー
    2. カーネルのメモリ内にページテーブルを作って、仮想物理アドレス空間を紐づける
    3. 所定のアドレスから実行
  • mmap関数:ページ単位で仮想メモリ取得、大きめメモリをプールしておく→その後malloc関数:バイト単位でメモリ取得
  • ファイルマップ:mapp()を所定の方法で呼び出すことで、ストレージデバイス内の該当ファイルをメモリに呼び出す→その空間を仮想アドレス空間マッピングできる
  • デマンドページング:
    1. プロセス生成時に仮想アドレス空間内の領域を獲得、が物理アドレスには未割当
    2. プログラムがエントリポイントから実行されると、CPUにてページフォルトが発生し、カーネルページフォルトハンドラが物理メモリにアドレスを割り当てる…続く
  • コピーオンライト;fork()時は、親プロセスのページテーブルを子プロセスにコピーする(一緒の物理アドレスを指している)この時書き込み権限は無効化されている
    • 親・子どちらかがページを更新したいとき
      1. カーネルページフォルトハンドラがアクセスされたページを別の場所にコピーして、書き込みしようとしたプロセスに和知宛てる
      2. 親・子それぞれ共有が解除されたページに対応するページテーブルを書き換える
      3. 書き込みしたい側は新たな物理ページと紐づけて、書き込みの許可をする。
      4. もう片方の当該ページも書き込みの許可をする
        親と子で共有されているメモリは、それぞれのプロセスで二重計上される
  • スワップ:ストレージデバイスの一部を一時的にメモリの代わりとして使用する。物理メモリが枯渇した際、使用の一部をストレージに退避させる。メモリを退避させる領域をスワップ領域(windowsでは仮想メモリ)、退避させることをスワップアウトという。取り戻すことをスワップイン、合わせてスワッピングという
    • どの領域を退避させるかの判断はカーネルのアルゴによる
    • スワッピングが頻繁に行われることをスラッシングといい、重くなる。
    • スワッピングのようにストレージへのアクセスが発生するページフォルトメジャーフォルトという
  • ヒュージページ;プロセスのべージテーブルに必要なメモリ量を減らせる、データベースなど仮想メモリを大量に使用するときに検討すると吉

6. 記憶階層

  • コンピュータの動作の流れ
    1. 命令をもとに、メモリからレジスタにデータを読み出す
    2. レジスタ上のデータをもとに計算する
    3. 計算結果をメモリに戻す
  • レジスタのメモリのやり取りのところで時間がかかる→キャッシュメモリを利用
    • キャッシュメモリ:基本CPU内にある。メモリのデータをキャッシュメモリにキャッシュする
      • レジスタの値が変えられたら、まず変更データをキャッシュメモリに上書きして、ダーティという印をつける→バックグラウンド処理としてメモリに書き戻される(キャッシュメモリはダーティでなくなる)
      • 階層型でレベルが存在する。一番レジスタに近く、容量が少なく、高速なのがL1
      • /sys/devices/system/cpu/cpu0/cache/index0/:cpu0のL1キャッシュの情報
    • ページキャッシュ:ストレージのデータをメモリにキャッシュすること ‐ プロセスがファイルのデータを読み出す場合、まずカーネルのメモリ上のページキャッシュ領域にコピーして情報を保持→そのデータをプロセスのメモリにコピーする.再度呼び出された場合早く呼び出せる。
      • プロセスにより更新されたら、ページキャッシュにデータを書き込んでダーティマークをつける ‐ ダーティページが多い&メモリ不足なシステムライトバック(ページキャッシュからストレージへの書き込み)が頻発するため遅くなる
        • sysctl vm.dirty_writeback_centisecs: ダーティページのライトバック周期センチ秒(1/100秒)
        • sysctl vm.dirty_background_radio: 全メモリの内、表示された割合のダーティページが超えた場合、ライトバック処理が走る
      • ページキャッシュ&バッファキャッシュ=ストレージ内のデータをメモリ上に置いておく仕組み(ざっくり)
      • echo 3 > /proc/sys/vm/drop_caches: システムのページキャッシュを削除する
  • ハイパースレッド機能:CPUコア内のレジスタなどを複数用意して、それぞれを論理CPUと認識されるようにするハードウェア機構スループットが単純に倍になるという訳でもない。
    • /sys/devices/system/cpu/cpuNum/topology/thread_siblings_list: ペアとなるスレッドの表示

7. ファイルシステム

  • どこにどんなデータがあり、どこに空き領域があるか管理する仕組み
  • linuxは複数のファイルシステムを扱える(ext4, XFS, Btrfs... ストレージデバイス上に存在する)
  • データ(データの中身・内容)とメタデータ(種類・時刻・権限情報)の2種類がある
  • ファイルシステムごとに使用できる容量を制限する機能があり、クォータという ‐ ユーザクォータ、ディレクトリクォータ…
  • システム不整合を防ぐ方法
    • ジャーナリング(for ext4, XFS): 更新に必要な処理一覧をジャーナル領域(ファイルシステム内のメタデータ)に書き出す→更新中にシャットダウンしたら、ジャーナルログを最初からもう一度再生する
    • コピーオンライト(for Btrfs)
      • 前提としてコピーオンライト型のファイルシステムは、ファイルに更新が入ったら書き換えられた部分のみを別の場所にコピーする
  • tmpfs: メモリ上に作成するファイルシステム、再起動後はデータが消えている
    • mount | grep ^tmpfs
    • freeコマンドのsharedフィールドの値はtmpfsによって使用されているメモリ量(KB)
  • ネットワークファイルシステムリモートホスト上のファイルにアクセス。windowsはcifs, UNIX系はnfs

8. ストレージデバイス

  • HDD
    • プラッタという磁気ディスク
    • セクタ単位で読み書きする
    • スイングアームという針のようなものが上下することでセクタを選び、先端の磁気ヘッドで読み書きする
    • ブロックデバイス:ランダムアクセス可能で、一定量(セクタ)ごとにアクセス可能なデバイスの事
      • 大体ファイルシステムを介してアクセス
      • 各種ブロックデバイスに共通の処理はカーネル内のブロックデバイス層で対応
        • I/Oスケジューラ:ブロックデバイス層にある機能。マージ(複数の連続セクタのI/O要求を1つにまとめる)、ソート(複数の不連続なセクタへのI/O要求をセクタ番号順に並び変える)を行う ‐ 先読み機能:ある領域にアクセスした時、それに続く領域も読み取ること。もし使われなければデータを捨てる
  • SSD
    • データへのアクセスに機械的な動作がなく、電気的な動作だけで済む→HDDより高速
    • I/O支援機能により速さが下がることも。複数のI/O要求をためておく処理のオーバーヘッドがSSDでは無視できないため ‐ point
      1. ファイル内のデータを連続する or 近い領域に配置する
      2. 連続する領域へのアクセスは、複数回に分けずにまとめる
      3. ファイルにはなるべく大きなサイズでシーケンシャルアクセスする

使ったコマンド💻

  • strace: プロセスが呼び出すシステムコールをみる
  • sar: プロセスがユーザーモードカーネルモードのどちらで実行しているのかみる
    • sar -P ALL 1(1秒ごとに見る) sar -P ALL 1 1(1秒ごとに1回測定)
    • ユーザーモード→%userと%niceの合計 ‐ カーネルモード→%system
    • sar -q 1 1: runq-szフィールド→実行中or実行待ちプロセス数
    • sar -r 1: 1秒ごとのメモリ状況。kbmemused->物理メモリ使用量、kbswpused->スワップ領域の使用量、kbpgtbl->ページテーブルに使用している量, kbcached->ページキャッシュの総量(kb)
    • sar -W 1: ``ごとのスラッシング確認、pswpin/sがスワップイン ‐ sar -d -p 1: ストレージデバイスに対するI/O量
  • ldd: プログラムがどのライブラリにリンクしているかみる
    • ldd /bin/echo ‐ readelf
    • readelf -h /bin/sleep: 開始アドレスを表示
  • /proc/pid/maps: プログラム実行時に作成されたプロセスのメモリマップ表示、仮想アドレスを表示
  • taskset: 指定の論理CPUで動作させる
    • task -c 0 ./sched
  • ps ax: 動かしているプロセスの確認
    • STAT: R->実行or実行待ち状態、S, D->スリープ状態(シグナルによって実行状態に戻るのがS), Z-> ゾンビ状態(親プロセスの終了待ち)
  • ps -eo pid,comm,etime,time: 経過時間(elapsed)と使用時間(time)
  • grep -c processor /proc/cpuinfo:論理CPUの数
  • timeコマンド:CPUの経過時間(real)と使用時間(user + sys,全コアの合計使用時間)がみれる ‐ time taskset -c 0 ./sched 1 10000 10000
  • nice -n 5 echo hello: 優先度5でecho helloする
  • free: memory容量確認(kバイト)
  • swap --show: システムのスワップ領域確認
  • cat /sys/kernel/mm/transparent_hugepage/enabled: トランスペアレントヒュー次ページの使用を確認
  • df: ファイルシステムのストレージ使用量
  • /proc/pid: 各プロセスの情報を得る
    • maps, cmdline, stat
    • /procにはその他ハード情報が盛りだくさん、詳しくはman procで ‐ /sys: procのようなカーネルのプロセスに関するもの以外の雑多な情報

prismaが生成するqueryをログに出す

prisma.service.tsを変更

import {
  INestApplication,
  Injectable,
  OnModuleInit,
  Logger,
} from '@nestjs/common';
import { PrismaClient, Prisma } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient<Prisma.PrismaClientOptions, Prisma.LogLevel> implements OnModuleInit
{
  private readonly logger = new Logger(PrismaService.name);
  constructor() {
    super({ log: ['query', 'info', 'warn', 'error'] });
  }
  async onModuleInit() {
    this.$on('query', (event) => {
      this.logger.log(
        `Query: ${event.query}`,
        `Params: ${event.params}`,
        `Duration: ${event.duration} ms`,
      );
    });
    this.$on('info', (event) => {
      this.logger.log(`message: ${event.message}`);
    });
    this.$on('error', (event) => {
      this.logger.log(`error: ${event.message}`);
    });
    this.$on('warn', (event) => {
      this.logger.log(`warn: ${event.message}`);
    });
    await this.$connect();
  }
  async onModuleDestroy() {
    await this.$disconnect()
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close()
    })
  }
}

graqhQLのtutorialやってみたメモ📝

situation

最近NestJSとprisma, graphQLを使ったAPI構築を勉強していて、 いまいちprismaとgraphQLの繋がりがふわふぁっとしていたので、howtogrqphQLという公式のtutorialをやってみた。 やっぱり公式はわかりやすい。。。

リマインドのために、サイトの訳(By 翻訳サイト)と自分の所感の雑記

公式サイト

memo

TS関係

  • @ts-ignore コメントをすると、次の行の型チェックが無視される
  • index.jsindex.ts はnodeJSではデフォルトのエントリーポイントと見なされる、最初に読み込まれるよ
  • 実行:npx ts-node src/script.ts

graqhQLのschemaって?

  • GraphQL schemas はGraphQL Schema Definition Language (SDL)の中で定義される
  • それぞれのGraphQL schemaは3つのオリジナルのroot typeを持つよ: Query, Mutation, Subscription
  • GraphQLは5このデフォルトのscalar typesがあるよ: Int, Float, String, Boolean and ID

Nexusライブラリについて

  • type-safe GraphQL schemasを生成するライブラリ、code-first approachで。
    • (´-`).。oO:graphQL schemaのtypeとかrootTypeをライブラリを使って書いて、生成していくのがcode-first approachって言うのかしらね。逆はSDL firstって言うらしいから、これは直接SDLを書きこむんだろうなぁ。
  • ①. Nexusを使って、graphQLのtypeやroot object typesを記述していく。
    • objectTypeはGraphQLの中で新しいtypeを作るために作られる。 ↓Userタイプの例
export const User = objectType({
    name: "User",
    definition(t) {
        t.nonNull.int("id");
        t.nonNull.string("name");
        t.nonNull.string("email");
    }
})
  • ②. コマンドnpx ts-node --transpile-only src/schemaでGraphQL SDL とtypesを生成する。-> typeとかQuery, Mutationは見た目的に完成
  • ③, 追加されたフィールドに対応するresolverを実装する

resolverって?

  • resolverはGraphQLフィールドの実装です。各タイプのすべてのフィールド(ルートタイプを含む)は、そのフィールドに対応するデータを返す役割を持つresolverが用意されています。
    • (´-`).。oO: resolverでデータのCRUD処理を実際にするイメージ
    • 例えばLinkというTypeとfeedというQueryがあった場合
type Link {
  createdAt: DateTime!
  description: String!
  id: Int!
  postedBy: User
  url: String!
  voters: [User!]!
}
type Query {
  link(id: Int!): Link
}
export const LinkQuery = extendType({
  type: "Query",
  t.field("link", {
            type: "Link",
            args: {
                id: nonNull(intArg())
            },  // ここまでlinkという名前のqueryを定義
        // ここから実際にlinkQueryがどういう処理をするか定義(Prisma利用)
            resolve(parent, args, context, info){
                // console.log(args) //{ id: 1 }
                const { id } = args
                return context.prisma.findUnique({
                    where: {
                        id: id
                    }
                })
            }
        })
  },
  • GraphQLサーバーがすべきことは、クエリに含まれるフィールドに対してすべてのresolverを呼び出し、クエリの形状(この場合Link)に従ってレスポンスをパッケージ化することである。このように、クエリーの解決はresolverの呼び出しをオーケストレーションするプロセスに過ぎないのである。
  • (´-`).。oO: GraphQLのQueryは該当するresolverを呼び出して、うまくまとめて返してくれるのね
  • all GraphQL resolver functionsは常に4つの引き数を受け取る: parent, args, context, info
    • contextとは?: context 引数は JavaScript のプレーンなオブジェクトで、リゾルバーチェーン内のすべての リゾルバーが読み込みと書き込みを行うことができる。したがって、これは基本的にリゾルバが通信するための手段である
    • Prisma Clientをcontextにぶっこむと、resolver内からPrisma Clientにアクセスできます!
    • Prisma Clientには、データベースに対するクエリーを実行するために必要なものがすべて含まれています。
    • Prismaのクエリは、非同期なのでPromiseオブジェクトを返します。
    • parentのくだり

PrismaとgraphQLの関係

  • (´-`).。oO: GraphQLがこーゆー名前のqueryもしくはmutationの処理あるよ、それは何を返すよって、宣言して、実際そのデータのCRUD処理を行うのがresolverで、データベースを使うときにはprismaを使ってCRUD処理のやりとりをdbとしてるって感じ。
  • (´-`).。oO: 例えばこーゆタイプ(User)があるよ、その中でこういうリレーションがあるよって示しているのがSDLで、実際にそのリレーションのデータのやり取りをするのがresolveって感じ
  • objectType内でもrelationがあったらresolveする。↓
// in User.ts>User = objectType

t.nonNull.list.nonNull.field("links", {    // 1
            type: "Link",
            resolve(parent, args, context) {   // 2
                return context.prisma.user  // 3
                    .findUnique({ where: { id: parent.id } })
                    .links();
            },
        }); 
  • 上について公式曰く: リンクフィールドのリゾルバは自明ではないので、データベースから返されるUserオブジェクトが自動的にリンクタイプを含まないため、GraphQLは自動的にそれを推論することができません。→(´-`).。oO: type: Linkって言われても、何すりゃいいねん@graphQL.。   このため、Userタイプの他のフィールドとは異なり、リンクのリゾルバを明示的に定義する必要があります。
  • 上のコードの.links()について:prisma.shcemaのUser modelに記述している
links     Link[]        @relation(name: "PostedBy")

のlinksのことを指しているっぽ

  • (´-`).。oO: prisma shemaに書いても、objectTypeに記述しないと、graphQLには反映されないんだなぁ
  • 多対多のrelationならそれぞれのobjectTypeにその旨記載

その他

  • idArg: string, intArg(): intで詰まる
  • [User!]!の意味:空のリストか、NULLでないUserオブジェクトのみを含むリストを受け取るの意
  • pagination: Prisma Client APIは、findManyクエリの追加オプションとしてskiptakeの引数を受け取り、それに応じてリンクレコードを返します。

参考できるもの

github.com

sql-zooなるもの

最近SQL-ZOOをコツコツ進めていた。

SQL-ZOOとは、SQL文を基本から例題を解くことで学んでいこうというブラウザのコンテンツ。 ブラウザ上ででsubmitすると正否だけ表示されて、分からないときに答えを見ることはできない。 だけど、SQLを学ぶコンテンツとしては有名なようで(自分も前誰かから教えてもらったし)、 ググったりgithubを検索すると先人の素晴らしいanswerを色々見れます 。

自分もちょくちょくGItHubに解答を載せています↓

https://github.com/kumo2kumo/sql_zoo

ISUCONきっかけでSQLを学びたい欲ができた。

オライリー・入門Python3のメモ

入門Python3をようやく読めた。 メモと章末の復習課題のまとめ

【ISUCON11】ISUCON初参加2021 SUMMER 〜諸々no知識だったけど参加してみたらお祭りだった〜

ISUCON11にこの夏参加してきました!ISUCON
準備期間から本番まで非常に素敵な時間を過ごせた。ざっと備忘録

 

きっかけ

今年5月までISUCONの存在すら知らなかった。
とあるエンジニアさんから

ISUCONはエンジニアの夏の大運動会、技術と技術のガテン系ぶつかり合いのお祭り、おもしろいよ!

と教えてもらって気になっていた。
そんな矢先、Code Polarisdzさんから、ISUCONやりませんかー、とのありがたい募集が!これは運命、神の見えざる手のお導きと諸手を挙げて参加表明、そのままdzさんとチームを組ませてもらうことに。

結果声を大にして言いたいことは、ISUCONは楽しかったよ!

チームは別だけど、CodePolarisとして一緒に参加したkaoriさんもISUCONブログ書かれてました(●´∀`)v↓↓

zenn.dev

 

事前に取り組んだこと

  • 公式:ISUCONの事前講習2つ
    • 座学:とりあえずマニュアル読むの超大事ということと、ISUCONはみんなの母ということを学ぶ
    • ハンズオン:公開鍵を生成してgithubに置いたり、sshでのログインなど、最初からほとんどやった事ないことばかりで戸惑い(; ・`д・´)         途中、サーバー上のコードってどうやってローカルに持ってくるの?と右往左往する。とりあえずVimVim!                   ベンチ回して、修正して、また回して…とこんな流れでやるのか〜と雰囲気を羽毛布団並みのふわっっと感で掴む。あとは去年の事前講習動画も見た。

     本番前から着々と前夜祭が盛り上がりを見せていました

 

 ↓↓個人でやったこと↓↓

  • Isucon9予選少しいじり:alpやスロークエリの使い方を学ぶ@AWS。インバウンドルールを適切に設定していないことにより、時たま詰まる。
  • dzさんと会議:当日の集合時間から、最初これをやろうなど決めたことをリスト化。あらゆる無料枠の登録やリポジトリの作成も事前に完了!
  • SQLのおべんきょ:せっかくだしあんまやったことないSQLもちょろっと勉強してみよう、とわかりみSQLをさらっと読む。INDEXという存在を知る。Redisについても学びたかったな…間に合わず。
  • Vtuberさん動画垂れ流し:Vtuberさん3人が5時間でISUCON問題を解いてみる動画。皆さんの役割分担がインフラ・総統括とアプリ改修に綺麗に分かれていて流れるように作業していらっしゃる。

    youtu.be

     

本番  

10:00 :開始。node.jsで取り組むことにするcloudFormationから3台起動。マニュアル読み合わせを始めるも、長くて途中で一旦止め!笑

10:30 :無事ssh接続完了👏👏

11:00 :GitHubに必要なとこだけ(etcとwebapp)pushするのに四苦八苦。

何も考えずbench回す、2000点ぐらい? serviceをnodejsに変更→1100点ぐらい。3台のスペックを把握。どれも一緒ぽい。

12:00 :logのクリアやらサービス再起動するスクリプト作成。あれもう12時か、何もしてないぞ

14:00 :レポジトリのpushができるようになる。→権限回りの問題だった模様、dzさんが改修してくれた…ありがたや👏

slow-query onにするも、permission deniedで書けないよと、error.logに書いてある。。。権限色々変更でいけた。dzさんはアプリ側のチェック。alpで状況見たりしてくれている。アプリ側、お任せします…!(私はちんぷんのかんです)

pt-query-digestで時間かかってるquery把握からの、index貼る、score3000に上がった!上がったー!👏

やばいぞ楽しいぞー!

15:30 :nginx周りの設定を見る、cache周りなど少し設定を変えてみる score5000みたけど幻?

17:00    :SQLを別サーバに切り出しやろうかと思ったけど、時間間に合うか…でやめた。portalがつながらないー!時間経つの早いー!とキャッキャしていた。

で終了。結局ごはんもいらないほど8時間集中していて、あっという間に終わってしまった。

最終スコアは4184でした!もう、少し上げられただけでも私からしたら嬉しいのですよ…(´;ω;`)ただ上位の神々達はうん百万とかうん十万のスコアを叩き出していて、もう頭を垂れてひれ伏すしかありません。そんなスコア上がるのか…と夢も広がる

 

これからやりたいこと(ざっと)

  • Pythonでやってみたい。ぱっと見Flask使っているようなので、少しFlaskさらって取り組む
  • manual、documentもう少し読みこむ
  • 分散化
  • SQL学ぶ
  • 公式の講評や、Discordのrandomチャンネルの神々達の話を読んで改良したい

はぁ~楽しかった。来年も参加したい。どんどん募集締め切りが早くなってきている(今年は数時間だったかな?)らしいけど、人気なのもわかる。

運営の皆様お疲れさまでした、ありがとうございました!

isucon.net

 

 

 

アセンブラ言語に触れてみて、ユニバース

ここ最近アセンブラ言語を始めました。

2進数、16進数とワタクシ人生史上一番触れ合っているかもです。

(今までがふれあいなさすぎた)

流れとしては

アセンブリしたらDS,DCで宣言してた変数が主記憶装置にセットされる(16進数)

・1行進めるごとに、レジスタと主記憶でデータのやり取りを行ったり、

レジスタ内で演算したりする

 

今現在↑な流れをつかんでいる。

他の言語でも、スクリプトが呼ばれたら、大量の(グローバル)変数を主記憶装置にセットして各々アドレスがあって、

ものすごい速さでそれらとCPUとでやりとりして…

っていうPCの仕事っぷりを想像しただけで、自分的に天文学的過ぎて

頭が爆発しそうになった。

それを無言で淡々とやる(たまに温度上がって熱くなってるけど)PCってすごくない?

宇宙だわ、ユニバースだわ