
JITベースのユーザースペースLinuxカーネル。仮想マシンなしでApple Silicon macOS上でネイティブにコンテナを実行します。コンテナ隔離、オーバーレイイメージ、ポート公開を備えたドロップインのDocker Engine API置き換えです。
仮想マシン不要でmacOS上でLinuxコンテナを実行。
dd は、Apple Silicon macOS 上で Linux コンテナを仮想マシンなしでネイティブ実行します。以下に Linux カーネルもハイパーバイザーも存在しません。JIT がコンテナのコードを変換し、その Linux システムコールをユーザースペースで処理します(gVisor / PRoot 系統)。JIT がゲストの Linux カーネルそのものです — 名前空間、cgroups、オーバーレイイメージレイヤ、ネットワーキングはすべてユーザースペースの状態として維持されます。Docker Engine API を話すため、通常の docker CLI で操作できます。
コンテナの 計算 はネイティブの Apple Silicon 命令として実行され、システムコール のみが解釈されます。起動する VM も、VM 内のデーモンも、仮想化のオーバーヘッドもありません。
ウェブサイト & ドキュメント: https://ricccrd.github.io/dd/
make jit # build.rs が JIT をコンパイル&コード署名
DD_IMAGES=/path/to/images cargo run -p dd-daemon # デーモンを起動
export DOCKER_HOST=unix://$PWD/dd.sock
docker run -p 8080:80 -m 256m alpine sh -c 'echo hi from $(hostname)'
DOCKER_HOST をそのソケットに向ければ、既存の docker run / ps / images / build コマンドがそのまま動作します。jit86) が x86 をデコードし、フラグを合成し、SSE/x87 を NEON に変換 — glibc バイナリが動作)、および macOS arm64 ゲスト (ddcli mac) — いずれも VM は不要。.wh. ホワイトアウト、マージされた getdents)、TOCTOU フリーのパス監獄 VFS、PID / UTS / USER 名前空間、-p ポート公開機能付きプライベートループバック netns、cgroup メモリ+pids 制限(制限時に OOM)。dd CLI により、ユーザーごとのバックグラウンドデーモンと docker context をインストール — すべて $HOME 下で動作し、sudo は不要。Mac 上で Linux コンテナを実行する他のすべての方法 — Docker Desktop、Colima、Rancher、OrbStack — は、ハイパーバイザーの下で Linux VM を起動し、デーモンをその 内部 で実行します。その VM は一日中払い続ける税金です。dd はそれを削除します:コンテナはプレーンな macOS プロセスであり、そのシステムコールがたまたまユーザースペースの Linux カーネルによって処理されるだけです。
この勝利は構造的なものです:ゲストの 計算 は ネイティブの Apple Silicon 命令 として実行され(ホットパスにハードウェア仮想化レイヤはなし)、Docker Desktop の悪名高いファイル共有のボトルネック — macOS と VM の間の virtiofs/FUSE ブリッジ — は単純に存在しません。なぜなら dd の VFS はパス監獄の背後にあるホストファイルシステムそのものだからです。
正直なトレードオフ: ユーザースペースカーネルは実装されたシステムコールの範囲によって完全性が決まり、今日デフォルトではゲストは 1 プロセス で動作します — 高速であり、信頼できるコード(あなたの開発環境、CI、自身のツール)には適切な選択です。信頼できない コードに対しては、オプトインの セントリ分割 (
DDJIT_UNTRUSTED) が用意されています:ゲストはホストのファイルシステム/ネットワーク権限を持たないデフォルト拒否の Seatbelt サンドボックス内で動作し、信頼された セントリ プロセスが実際のリソースを所有し、共有メモリリングを介してシステムコールを処理します — gVisor の形です。初期段階(コアファイルシステムコール — read/write/open/close/lseek — は現在転送されます。ソケット/exec/fork は準備中)のため、完全に敵対的なコードには VM の方が依然としてより狭い攻撃面を提供します。
同じ静的な Linux バイナリ を、Apple M5 Pro (macOS 26.3) 上で 2 通りで実行:Linux VM 内(VM ベースの Docker がコンテナを実行する方法) vs. dd の JIT をホスト上で VM なし で実行。7 回の中央値(make bench)。低い時間ほど良好。「dd vs VM」> 1× は dd の方が高速であることを意味します。dd のレーンは実際のアプリでは発生しない小さなプロセス間ブリッジのオーバーヘッドも支払っているため、これらは 保守的な 数値です。
x86-64 コンテナ — dd vs VM エミュレーション(qemu-user; Apple Silicon 上で x86 を実行するということは、どちらにせよ 変換 することを意味します)。dd の JIT は 10 のワークロード中 9 つ で qemu を上回り、浮動小数点では劇的に優れています:
aarch64 コンテナ — dd vs ネイティブ VM(VM は arm64 をフルネイティブ速度で実行 — 最も難しい壁):
dd は arm64 の 計算をネイティブ速度で実行 — int sieve + mandelbrot で先行、SHA-256, matmul, memcpy, n-body, base64 で同等。残りのギャップは 間接分岐 / システムコールが重い 処理 — qsort (~1.3倍), text-scan (~1.35倍), SQLite (~1.5倍) — 最新のパス (§B-off + stolen x16/x17 により SQLite が ~1.9倍 から ~1.5倍 に改善) で大幅に縮小。残りのギャップ (VDBE ディスパッチ) は現在の最前線です。詳細は docs/design/arm-sqlite-parity.md を参照してください。(各ワークロードは 0.45 秒以上実行されるようサイズ設定されているため、ハーネスの小さな実行ごとのブリッジコストはここでは無視できます。)
これらは 計算 マイクロベンチマークであり、dd の構造的な利点(VM 不要、常駐 RAM なし、直接ホストファイルシステム I/O)すら捉えていません。すべての数値は測定済み、7 回の中央値。再現: make bench。
目標はすべてのベンチマークで VM に勝つことです。 dd は上記のすべての x86-64 ワークロードですでに勝利し、ネイティブ arm64 に匹敵または上回っています。依然として劣っている部分(システムコール/アロケーションが重い arm64 SQLite、および x86 トランスレータからのさらなる性能引き出し)は、まさに最適化の最前線です(tier-2 トレースオプティマイザーと jit86 パフォーマンス作業)。どこでも同等以上が目標です。
dd は Linux コンテナを そのカーネルをユーザースペースで実現する ことで実行します。JIT がゲストのマシンコードを変換し、すべてのシステムコール命令をトラップします。トラップハンドラ — dd-jit/src/runtime/os/linux/ 内の service() — が、macOS ホスト上で実装された Linux システムコール ABI そのものです。
ld.so 経由)をロードし、初期スタックを構築。# 1. デーモンを起動し、docker をそれに向ける
make jit
DD_IMAGES=/path/to/images cargo run -p dd-daemon
export DOCKER_HOST=unix://$PWD/dd.sock
# 2. それはただの Docker
docker run -p 8080:80 -m 256m alpine sh -c 'echo hi from $(hostname)'
docker ps
docker images
docker run --rm -it ubuntu bash
# 3. またはインストール済みデスクトップアプリ経由(ユーザー単位、root 不要)
dd install # LaunchAgent + docker context
dd app # GUI を開く
docker --context dd run alpine echo hi
dd は Apple Silicon macOS (arm64, macOS 12+) を対象としています。JIT には Xcode コマンドラインツール(clang + codesign)が必要です。
最新の .dmg を リリースページ から入手し、開いて dd をアプリケーションにドラッグしてください。その後、ターミナルで:
dd install # ~/.dd ツリー + ユーザーごとの LaunchAgent + `docker context create dd`
dd app # GUI を開く
dd doctor # ソケット / エージェント / コンテキスト / アプリ隔離状態を確認
Gatekeeper: DMG は署名されていません(アドホック)。初回起動時にはアプリを右クリックして「開く」を選択するか、
xattr -dr com.apple.quarantine /Applications/dd-app.appを実行してください(dd doctorがこれを検出し修正方法を表示します)。
xcode-select --install # clang + codesign
# Rust (stable) と Nix (GTK4 開発シェル用) をインストール
git clone https://github.com/ricccrd/dd && cd dd
make app # ビルド + アセンブル & アドホック署名 target/dd-app.app
make dmg # -> target/dist/dd-<ver>-<arch>.dmg
make install # /Applications にコピーし `dd install` を実行
make app/dmg は Nix 開発シェル(nix/flake.nix)内でバンドルを実行します。このシェルは GTK4 + dylibbundler / create-dmg を提供します。バンドルは GTK dylib グラフを Contents/Frameworks に再配置し、GTK ランタイムデータをステージングし、内側から外側へアドホック署名します。
Cargo ワークスペースです。
dd-jit/ — JIT ランタイム(C、src/runtime/ 下)とその Rust バインディング。build.rs はゲストアーキテクチャごとに 1 つの JIT バイナリ(aarch64, x86_64)をコンパイルしコード署名します。src/lib.rs は Guest + 型付き SpawnConfig 起動コントラクトを公開します。aarch64 ゲストは完全に分解されています(jit/ エンジン + os/linux/ パーソナリティ + frontend/aarch64/)。x86-64 ゲスト (jit86) は os/linux/ レイヤを共有します。dd-daemon/ — Docker Engine API デーモン。各イメージのゲストアーキテクチャを ELF から検出し、対応する JIT を選択し、 経由で起動します。デーモンは ~/.dd/run/docker.sock で待機します。GUI と docker --context dd の両方がこれを使用します。状態は ~/.dd/state.json に保存されます。
make test # エンジン × ケース マトリックス、グループ化レポート
make test ENGINE=x86_64 # 1 つのエンジン
make test FILTER=container # 名前が一致するグループ / ケース
cargo run -p dd-tests -- --list # グループ + ケースを一覧表示
make test-ci # cargo-test パス (CI)
ケースは dd-tests/src/cases/ で宣言されます。ケースはゲストプログラム + アサーションです。aarch64 ゲストはその場でコンパイル (gcc -static-pie) され、ネイティブオラクルと比較されます。x86-64 ゲストは事前ビルドされたフィクスチャから提供されます。各ケースは、そのケースのゲストを持つすべてのエンジンで実行されます。
clang + codesign (Xcode CLT) が必要。-p)、プライベートループバック netns、cgroup メモリ+pids 制限、UTS/PID/USER 名前空間。docs/ を参照。Richard Hutta — [email protected]
MIT.
| dd — ユーザースペースカーネル (JIT) | VM ベースの Docker (Desktop / Colima / …) |
|---|
| 基盤モデル | JIT が Linux システムコールをユーザースペースで処理 (gVisor 系統) | ハイパーバイザー VM 内の完全な Linux カーネル |
| アイドル時の常駐 RAM | なし — コンテナごとに割り当てられ、終了時に解放 | 常時オンの VM に数 GB 予約 |
| 起動 | プロセス生成 — 起動する VM なし | 最初に Linux VM + VM 内デーモンを起動 |
| バインドマウント / ファイル I/O | パス監獄を通じた直接ホストファイルシステム | VM 境界を越える virtiofs/gRPC-FUSE ブリッジ |
| ポート公開 | ホストソケットに直接 | VM の NAT/フォワーディングレイヤ経由 |
| バッテリー / バックグラウンドコスト | コンテナがなければ 何も 動作していない | VM がアイドリングしバッテリーを消費 |
| 出荷・パッチのフットプリント | Linux カーネルなし — CVE 追跡不要 | 完全な Linux カーネルを出荷、パッチ、追跡 |
| 可観測性 | 通常の macOS プロセス — サンプリング、デバッグ、アクティビティモニタ | 不透明な VM。ワークロードはホストツールから見えない |
| ワークロード | VM (qemu) | dd (VM なし) | dd vs VM |
|---|
| float n-body | 5.39s | 0.23s | 24倍高速 |
| mandelbrot | 7.81s | 0.83s | 9.4倍高速 |
| matmul | 8.21s | 1.37s | 6.0倍高速 |
| SQLite (600k 行) | 2.99s | 1.01s | 3.0倍高速 |
| qsort | 3.91s | 1.68s | 2.3倍高速 |
| memcpy | 2.40s | 1.10s | 2.2倍高速 |
| text-scan (wc/grep) | 1.42s | 1.11s | 1.3倍高速 |
| int sieve | 1.31s | 1.04s | 1.25倍高速 |
| SHA-256 | 2.72s | 2.44s | 1.1倍高速 |
| base64 | 4.28s | 5.39s | 0.79倍 (1.26倍低速) |
| ワークロード | VM (ネイティブ) | dd (VM なし) | dd vs VM |
|---|
| int sieve | 0.75s | 0.48s | 1.58倍高速 |
| mandelbrot | 0.79s | 0.77s | 1.03倍高速 |
| matmul | 0.66s | 0.66s | ~同等 |
| memcpy | 0.55s | 0.56s | ~同等 |
| base64 | 0.68s | 0.68s | ~同等 |
| float n-body | 0.17s | 0.17s | ~同等 |
| SHA-256 | 0.80s | 0.82s | ~同等 |
| qsort | 0.83s | 1.10s | 1.33倍低速 |
| text-scan (wc/grep) | 0.51s | 0.68s | 1.35倍低速 |
| SQLite (600k 行) | 0.36s | 0.62s | 1.71倍低速 |
SpawnConfigdd-tests/ — 宣言的テストハーネス。ケースはすべてのエンジンで実行され、グループ化されたレポートを生成します。dd-client/ — デーモンの Unix ソケット上に実装された小さな型付き Docker Engine API クライアント(ワイヤフォーマットの唯一の信頼源で、GUI と CLI で共有)。dd-gui/ (バイナリ dd-app) — GTK4 デスクトップ UI。macOS 上でのみ Nix 開発シェル経由でビルド。dd-cli/ (バイナリ dd) — インストール/制御面。root 不要。