90年代の SIMD:Intel の Pentium MMX をプログラミングする

2026/08/13 21:44

90年代の SIMD:Intel の Pentium MMX をプログラミングする

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

インテルの MMX テクノロジーは、1997 年に Pentium MMX プロセッサと同時に出荷され、パックされた整数演算および固定点数学のための新しい 57 の命令を追加することでマルチメディア性能を強化することを目的として設計されました。これは、既存の x87 フローティングポイントレジスタの下位半分を再利用して作成された 8 つの 64 ビットレジスタ(MM0–MM7)を利用していました。この設計により、MMX 操作と標準的なフローティングポイントコードの間で厳格な排他性が強制され、MMX の使用後にプログラマーがこれらの共有リソースをクリアし、通常の計算に戻る前にバグを防ぐために

EMMS
命令を実行する必要がありました。独自のベクトルレジスタを備えた純粋な SIMD アーキテクチャとは異なり、MMX は共有された FP ステートへの依存関係により、重大な制約を招きました。

AMD などの競合他社は、SIMD アプローチを用いてインテルに対抗しようとしましたが(3DNow!、1998 年)、最終的にはインテルの優位性と、CPU 側のマルチメディアタスクの多くを引き継ぐ専用グラフィックハードウェア(例:Voodoo カード)の急成長により市場での牽引力を失いました。MMX は、128 ビットレジスタとネイティブなフローティングポイントサポートをもたらした、より優れた SSE 命令セットによって 1999 年および 2000 年に置き換えられました。その限界と最終的な時代遅れに尽管如此、MMX はベクトル化演算とデータ並列プログラミングのための基礎概念を確立し、現代的な CPU アーキテクチャへの道を整えました。

本文

Intel Pentium with MMX:90 年代後半の SIMD 革命とその後

はじめに

90 年代後半の PC プログラミングをされた方は、「Intel Inside Pentium with MMX」というラベルをご存知でしょう。MMX は単なるマーケティング用語ではなく、Intel がメインストリームのデスクトップ CPU にSIMD(Single Instruction, Multiple Data)指令セットをもたらすための重大な試みでした。

現代では AVX-512 や GPU 搭載など、豊富な歴史と互換性のノイズを伴う技術が存在します。しかし、MMX はその技術が始まった当時の状況から振り返るには最適な対象です。多くのプログラマーが当時、手書きアセンブリを使用して Pentium MMX から数フレーム分のパフォーマンスを引き出す方法を学んでいました。


Intel Pentium with MMX テクノロジー

1997 年へタイムトラベルし、MMX をプログラミングする様子を探っていきましょう。

MMX とは何だったのか?

MMX(MultiMedia eXtensions)は、1997 年に Pentium MMX プロセッサと共に導入されました。グラフィックやオーディオ処理などのマルチメディア体験向上を目的としており、Pentium チップに以下のような追加指令セットをもたらしました。

  • 追加指令: 57 条の新しい指令
  • レジスタ変換: CPU が MMX モードに切り替わる際、x86 の最初の 64 ビットを 80 ビットの浮動小数点レジスタからMMX レジスタへと変換する仕組み

8 つの MMX レジスタ(長さ 64 ビット)

MMX の核となるアイデアはシンプルです:CPU が一度に 1 つではなく、複数の整数を同時に処理することです。

  • 構造: 1 つの 64 ビットのレジスタに複数の整数を詰め込みます。
  • 効果: マルチメディアソフトウェア(画像処理、オーディオミキシング、動画再生など)において大幅なスピードアップをもたらしました。

具体的な例:並列加算

個別に 8 つのバイトを加算する場合の比較です。

通常の演算:

10 + 20
30 + 40
50 + 60
70 + 80
...

※各値を個別に処理する必要があります。

MMX を用いた演算:

  • 上記のすべての加算を1 つの指令で実行可能です。
  • これが「並列処理」であり、SIMD の本質です。

SIMD とは何か?

「Single Instruction, Multiple Data(1 つの指令、複数のデータ)」は、以下の定義を持つ並列処理技術です。

定義: 複数のデータポイントに対して同時に同じ演算を行う複数の処理要素を備えたコンピュータにおける技術。

  • 実装方法: ハードウェア設計として内部に実装され、ISA(命令セットアーキテクチャ)を通じて直接アクセス可能です。
  • MMX の役割: Intel が x86 指令セットを拡張し、新しい SIMD 指令を含めることで対応しました。

MMX は初の SIMD であったか?

いいえ、MMX は決して最初の SIMDではありません。ただし、SIMD をx86 PC では主流にする上で極めて重要な役割を果たしました。

歴史的背景:ILLIAC IV

  • 時代: 1960 年代
  • プロジェクト: ILLIAC IV スーパーコンピュータ
  • 特徴: 最初の massively parallel(大量並列)コンピュータの一種
    • 256 つの 64 ビット浮動小数点演算単位(FPU)を備える
    • 1 秒間に 10 億回の演算処理が可能
    • 4 つの CPU を搭載

ILLIAC IV ILLIAC IV の写真(Sascha Pohlflepp 氏による CC-BY-2.0)

また、1970〜80 年代の CDC や Cray などからアレイ処理マシンも登場しました。

SIMD とアレイプロセッサの違い

ベクトル処理と SIMD は完全に同一ではありません。主な違いは以下の通りです。

  • 提示方法: データ要素がプロセッサに与えられる方法
  • 実行方法: ハードウェアによる実装の違い
  • SIMD の特性: レジスタの幅と密接に関連している

Cray-1 との比較

1976 年のベクトルプロセッサである Cray-1 は、それぞれ 64 ビットの値を保持する 8 つのベクトルレジスタを持っていました。

Cray-1 Cray-1 スーパーコンピュータ

SIMD と同様に、Cray-1 は個別の ADD 指令を 64 回発する必要はありませんでした。しかし、それを「SIMD」と呼ばない理由はアーキテクチャ的な区別にあります。

特徴SIMD (MMX)Cray-1 (ベクトルプロセッサ)
動作原理固定幅のレジスタ上で動作コンテナのような構造
制御ベクトル機能ユニットは単一のサイクルで処理
SET VECTOR SIZE
指令あり、複数のサイクルにわたって処理可能

注釈: Cray-1 は VL(ベクトル長)レジスタを持っており、最大 64 要素を処理できました。VL=0 は「すべての要素(64 個)」として解釈されました。

MMX の真の重要性

MMX の真価は、比較的手頃な SIMD 命令セットをメインストリームの x86 PC に持ち込んだ点にあります。

  • レトロコンピューティングにおいて注目を集める理由の一つです。
  • SIMD が専門分野から通常のデスクトップソフトウェア開発へと移行した瞬間の技術と言えます。

MMX レジスタとデータ形式

レジスタの再利用

Intel は新しいレジスタを追加するのではなく、既存のx87 浮動小数点スタックレジスタを再利用しました。

  • MMX レジスタ:
    MM0
    MM7
    (計 8 つ)
  • 構造: 内部では x87 レジスタのエイリアスとして機能
  • : 実質的に 64 ビットのみアクセス可能(元は 80 ビット)

この設計はシリコンを節約しましたが、重要な制限も生じました。

排他的な実行環境

SIMD と浮動小数点演算は互いに排他的です。 MMX は x87 のレジスタを「占有」するため、両者は同時に動作できません。

  • 重要ルール: MMX コードと x87 浮動小数点コードを混ざらせないこと。
  • 対策: MMX 処理前後に必ず状態を整理する必要があります(後述する
    EMMS
    で解決)。

データのレイアウト(パックされた整数)

1 つの MMX レジスタには以下の 4 つのレイアウトを持たせることができました:

レイアウト名称内容
MMIMultiMedia Integer8 つの 8 ビット整数
MPIMultiMedia Packed Integer4 つの 16 ビット整数
QPIQuad Packed Integer2 つの 32 ビット整数
LPILong Packed Integer1 つの 64 ビット整数

初めての MMX プログラム:実践例

単純な加算の最適化

8 ピクセルを加算する場合(コンパイラ最適化なし)での比較です。

スカラー版(通常の C コード)

for (int i = 0; i < 8; i++) {
  dest[i] = src1[i] + src2[i];
}

MMX 版(アセンブリコード)

movq mm0, [src1]      ; 8 バイトをロード
movq mm1, [src2]      ; 8 バイトをロード
paddb mm0, mm1        ; 8 つのバイト加算を同時に実行
movq [dst], mm0       ; 結果を格納
  • 効果: 1 つの指令で 8 つの個別な加算が置き換えられます。

MMX の強力な特徴:飽和演算(Saturation)

通常の整数演算ではオーバーフローすると値が「巻き戻ります」(例:

250 + 20 = 270
14
)。グラフィック作業では望ましくありません。MMX は飽和(最大値にクリップ)機能を提供します。

飽和加算指令

paddusb mm0, mm1
  • us: Unsigned Saturation(符号なし飽和)
  • 動作:
    250 + 20
    の結果を
    255
    にクリップします。
  • 効果: ピクセルの輝度調整やブレンド操作が容易になります。

パーフェクトな比較処理

すべての値よりも大きなものを白に変えるマスクを作成できます。

pcmpgtb mm0, mm1
  • 結果: 各バイトが
    0xFF
    (真)または
    0x00
    (偽)になります。
  • 用途: しきい値フィルタ、スプライトの透明度判定、衝突ロジックなど。

パックされた値のシフト

ビットシフトは乗算・除算の高速な代替手段です。MMX はパックされた値を同時にシフトできます。

psllw mm0, 1  ; すべての 16 ビット値を 2 倍にする(左シフト)
psrlw mm0, 1  ; すべてを 2 で割る(右シフト)

パックされた乗算

定点数計算などで 2 の倍数以外の数での乗算が必要です。MMX はこれをサポートします。

pmullw mm0, mm1
  • 動作: 各ペアの 16 ビット整数を独立して乗算。
  • 用途: オーディオボリュームスケール、画像畳み込み、色変換など。

実践的な例:画像明るくするルーチン

以下のコードは、画像全体を一定値(20)だけ明るくし、最大値 255 で飽和させる処理です。

スカラー版(C)

int intensity = 20;
for (int i = 0; i < WIDTH * HEIGHT; i++) {
  pixels[i] += intensity;
  if (pixels[i] > 255) {
    pixels[i] = 255;
  }
}

MMX 版(アセンブリ)

一度に8 ピクセルを処理します。

section .data
    intensity: times 8 db 20 ; 20 を 8 つ重複させる (0x14)

section .text
    ; esi = ピクセルへのポインタ
    ; ecx = 8 ピクセルのチャンクの数

loop:
    movq    mm0, [esi]          ; 8 ピクセルをロード
    movq    mm1, [intensity]    ; 8 つの 20 をロード
    paddusb mm0, mm1            ; 飽和加算(自動クリップ)
    movq    [esi], mm0          ; 結果を格納

    add     esi, 8              ; 次の 8 ピクセルへ
    dec     ecx
    jnz     loop

    emms                        ; MMX ステートをクリアして終了

重要な注意点:EMMS 指令

MMX は x86 の浮動小数点レジスタから「借入れ」しているため、使用終了時に状態をリセットする必要があります。

emms
  • 機能: MMX ステートをクリアし、x87 浮動小数点指令の正常動作を再開します。
  • 注意点:
    EMMS
    を呼び忘れると、後の浮動小数点計算で奇妙なバグが発生します。必ず使用後(および浮動小数点コード前)に挿入してください。

ゲームにおける MMX の活用状況

使われたのか?

MMX が直接ゲーム処理に使われるのは限定的でした。1997 年当時、GPU やアクセラレーションカード(S3 ViRGE, Voodoo など)の登場により、CPU 側だけで負荷を担う必要性が減っていました。ただし、以下の用途で MMX は有益でした。

  • ソフトウェアテクスチャマッピング
  • スプライト合成
  • アルファブレンド
  • 画像スケーリング
  • MP3 デコーディング
  • モデムソフトウェア
  • MPEG 動画再生
  • オーディオミキシング

具体例:Comanche 3

Novalogic の「Comanche 3」開発者の Kyle Freeman は、MMX がオーディオとグラフィックの両方で多用されたことを証言しています。

Kyle Freeman Kyle Freeman のツイート:Comanche 3 で MMX が使われたこと

その他ゲームとの関係

  • Eraser Turnabout, POD, Extreme Assault: ソフトウェアレンダラーで MMX 拡張を要求・利用した例。
  • Tomb Raider: 噂にはあるが、信頼できるソースでの実装は不明。
  • Quake / Quake II:
    • Quake (1996) は Pentium MMX (1997) のリリースより前であり、MMX を利用していない。
    • レジスタ割り当てやループ最適化による性能向上が主因。

対応戦略

MMX コードパスはオプションとして提供されました。数百万人のユーザーが古い Pentium を使用していたため、非-MMX バージョンも維持する必要がありました。


MMX サポートの検出方法

ソフトウェアは CPU が MMX をサポートしているかを

CPUID
指令で確認する必要があります。

mov eax, 1
cpuid               ; CPU の機能情報を取得
test edx, 1 << 23   ; EDX レジスタのビット 23 をチェック(MMX 支援フラグ)
jz NoMMX            ; 0 の場合は MMX なし処理へジャンプ

他のサポートも確認可能

  • Bit 25: SSE サポート
  • Bit 26: SSE2 サポート

AMD の 3DNow! とその行方

概要

1998 年、AMD は**3DNow!**という独自技術をリリースしました。

  • 概念: MMX に類似した SIMD 指令(ただし浮動小数点対応)を追加。
  • 搭載チップ: AMD K6-2 (1998 年)

AMD K6-2 3DNow! を搭載した AMD K6-2

Quake II (3.19) 以降のソースコードには、別途ビルドされた 3DNow! 最適化版(v3.20)が提供されました。

なぜ成功しなかったのか?

  1. 市場シェア: Intel が x86 市場を支配しており、MMX の普及率が高かったため。
  2. 互換性問題: Intel CPU と AMD CPU で動作保証の難しさ。
  3. Intel の反攻: 1999 年 Pentium III にSSEが導入され、決定的な打撃を受けました。

SSE による転換点

Intel の SSE は以下の理由で MMX および 3DNow! を上回りました:

  • 浮動小数点 SIMD: MMX の最大の制限(SIMD と FPU が共存できない)を解消。
  • 汎用性: スカラーおよびパックされた浮動小数点指令の両方をサポート。
  • 業界標準: ベンダーに依存しない共通規格として定着。

ただし、MMX は整数 SIMD(ピクセル処理など)において優れていたため、すぐに死にはしませんでした。SSE が 128 ビット XMM レジスタを導入したことで、MMX の機能がより強力なアーキテクチャに統合されました。


なぜ MMX は消えてしまったのか?

MMX レジスタが不要になった主な理由は、Intel SSE2(2000 年)の導入です。

  • SSE2: 128 ビット XMM レジスタを持ち、広範な整数 SIMD 操作を追加。
  • 比較例:
    • MMX: 一度に 8 ピクセル処理 (
      paddusb mm0, mm1
      )
    • SSE2: 一度に 16 ピクセル処理 (
      paddusb xmm0, xmm1
      )
; MMX (旧)
movq    mm0, [pixels]
paddusb mm0, mm1
movq    [pixels], mm0
emms

; SSE2 (新)
movdqu  xmm0, [pixels]
paddusb xmm0, xmm1
movdqu  [pixels], xmm0

結論:MMX の評価と意義

「魔法のターボボタン」ではない

Pentium MMX チップ自体が速かったのは事実ですが、MMX コードによってすべての処理が速くなるわけではありませんでした。キャッシュサイズ(16KB→32KB)などの要因も大きく寄与していました。

技術的移行として成功

  • ゲームやレンダリングには限界がありましたが、デジタル信号処理(オーディオ・モデム)では有効でした。
  • 「失敗」とは呼べない、PC プログラミングにおける重要なマイルストーンです。

今日に残される教訓

MMX は現代の SIMD 技術(AVX など)へと系譜を引いています:

  • パックされたデータの扱い方
  • ベクトル化算術の実践
  • 飽和操作の重要性
  • データ並列プログラミングの考え方

90 年代後半のプログラマーにとって、MMX は「アルゴリズムを個別値ではなくベクトルとして見る」視覚化の第一歩でした。


この記事は Intel Pentium with MMX テクノロジーの歴史と技術的な意義を振り返るものです。レトロプログラミングの魅力を再発見してください。

同じ日のほかのニュース

一覧に戻る →

2026/08/17 2:01

第 3 の世界組み込みエンジニアによる「RISC-V はもっと慎重だったべきだ」という批判への回答

## Japanese 翻訳: RISC-V は、ライセンス料という障壁によって競合他社(ARM など)が妨げられることなく、シームレスなスケーラビリティを提供するオープンアーキテクチャを有しているため、安価なマイクロコントローラー市場で支配的になると位置づけられています。Dmitry Grinberg 氏の「RISC-V:彼らはもっとよく知るべきだった」と題した論文に触発された議論において、トリニダード・トバゴ在住の組み込みエンジニアである Armstrong Subero は、Grinberg 氏の批判が発展途上国における重要な経済的現実を見落としていることを指摘しています。Grinberg 氏が安価なマイクロコントローラーへの要件を正しく特定したことは事実ですが、彼は単一の ISA(指令セットアーキテクチャ)内で低エンドおよび高エンドのニーズの両方を満たす RISC-V の能力を見積もり低估していました。Subero は、ARM が仮想メモリーといった高度な機能のためにユーザーがコアファミリーを切り替える必要(Cortex-M から Cortex-A など)とし、これには高額なロイヤルティ、販売交渉、そして多くの場合主要な小売業者での ID 検証の障壁を含む長いリードタイムが必要とされると反論します。一方、RISC-V は MMU や権限分離といった機能能力を、同じアーキテクチャ内のオプション拡張として扱い、契約上の壁を取り除いています。Subero は、アクセシビリティは単に技術的な設計のみならず経済的実現可能性にもよることを強調しています。発展途上地域へのチップの運搬コスト(他の地域で「送料無料」であるのに対して 60〜200 ドル)が、学生のアクセスを著しく妨げていると指摘します。Subero は、フラグメンテーションという主張に対し、具体的な RISC-V インプレメンテーションを挙げ反論しています:10 セントの CH32V003(RV32EC)、USB 3.2 Gen1 とイーサネットを搭載した高級二コアの CH32H417、そして Linux/seL4/Xous を実行する Baochip-1x SoC です。Subero は、このスタック全体の専門知識を習得するために運搬費だけで 100 ドル未満で達成でき、価格と入手可能性での勝利がグローバルアクセシビリティに決定的要因であることを示しています。AI 主導の需要が高騰させるにつれて ARM ライセンスコストが上昇する中、RISC-V は、発展途上国のエンジニアがアーキテクチャ的な妥協や金銭的ペナルティなしに高度な機能にアクセスすることを可能にする、より包摂的な代替案として登場しています。

2026/08/16 21:48

Claude: システムプロンプト

## Japanese Translation: 入力テキストは「Loading」文字列の繰り返しのみを含んでおり、実際のニュース、記事の内容、または物語構造を提供していません。したがって、関連する背景を確立するための日付、製品名、IT 詳細、または特定のデータポイントはいっさい含まれていません。テキストが実質的な情報を欠いているため、予測、将来の展開、または後続事件を示すことも、ユーザー、企業、あるいはより広い業界に対する含意を特定することもできません。その結果、情報提供レポートではなく汎用的なステータスインジケーターとなっています。

2026/08/17 3:48

Protobuf は LSP をサポートしています。ご自由にご利用ください。

## Japanese Translation: 原文の要約は、発表から技術的な詳細へ、そして今後の改善へと論理的に流れを続け、重要なハイレベル情報を欠かさずにキーポイント一覧の内容を正確に反映しており、よく書かれています。 ## Text to translate: **Repeat the original.** The original summary is well-written, flows logically from the announcement to technical specifics and then to future improvements, while accurately reflecting the content of the Key Points List without missing critical high-level information.