Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19714] ファイルの概要

コミット

commit 366f88f3e4449c609f3a5310c79536cfcd22f5c2
Author: Shenghou Ma <minux@golang.org>
Date:   Thu Jul 10 15:15:24 2014 -0400

    cmd/dist: always use GOARM=7 for nacl/arm
    
    LGTM=dave, rsc
    R=rsc, iant, dave
    CC=golang-codereviews
    https://golang.org/cl/101590044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/366f88f3e4449c609f3a5310c79536cfcd22f5c2

元コミット内容

cmd/dist: always use GOARM=7 for nacl/arm

このコミットは、Goのビルドツールであるcmd/distにおいて、nacl/arm(Native Client on ARM)ターゲット向けにビルドする際に、常にGOARM=7を使用するように変更するものです。

変更の背景

Go言語は、様々なアーキテクチャとオペレーティングシステムをサポートしています。ARMアーキテクチャは、モバイルデバイスや組み込みシステムで広く利用されており、その中で浮動小数点演算ユニット(FPU)のバージョンが複数存在します。Goのビルドシステムは、ターゲットとなるARMプロセッサのFPUの能力に応じて、最適なコードを生成するためにGOARM環境変数を使用します。

以前のcmd/distのロジックでは、ARMターゲットのFPUサポートを動的に検出していました。しかし、nacl/arm(Google Native Client for ARM)の場合、特定の環境下ではVFPv3(Vector Floating Point version 3)のサポートが常に保証されていました。従来の検出ロジックでは、このnacl環境の特性が十分に考慮されておらず、場合によってはVFPv3をサポートしているにもかかわらず、より古いFPUバージョン(例えばVFPv1)向けのコードが生成されてしまう可能性がありました。

このコミットは、nacl/arm環境ではVFPv3サポートが確実であるという前提に基づき、検出ロジックをスキップして直接GOARM=7(VFPv3を意味する)を設定することで、nacl/arm向けのGoバイナリが常に最適な浮動小数点演算性能を発揮できるようにすることを目的としています。これにより、nacl/arm上でのGoアプリケーションのパフォーマンス向上と、ビルドの信頼性向上が期待されます。

前提知識の解説

GOARM環境変数

GOARMはGo言語のビルドシステムで使用される環境変数で、ARMアーキテクチャ向けのコンパイル時に、ターゲットとなるARMプロセッサの浮動小数点演算ユニット(FPU)のバージョンを指定します。

  • GOARM=5: ARMv5アーキテクチャ向け。ハードウェア浮動小数点演算ユニットがないか、使用しない設定で、ソフトウェアによる浮動小数点演算が行われます。
  • GOARM=6: ARMv6アーキテクチャ向け。VFPv1(Vector Floating Point version 1)をサポートするハードウェア浮動小数点演算ユニットを使用します。
  • GOARM=7: ARMv7アーキテクチャ以降向け。VFPv3(Vector Floating Point version 3)をサポートするハードウェア浮動小数点演算ユニットを使用します。VFPv3はVFPv1よりも多くのレジスタと命令セットを持ち、より高性能な浮動小数点演算が可能です。

VFP (Vector Floating Point)

VFPは、ARMアーキテクチャのプロセッサに搭載される浮動小数点演算ユニット(FPU)の名称です。VFPは、単精度および倍精度の浮動小数点演算をハードウェアで高速に実行するために設計されています。

  • VFPv1: 初期バージョンのVFPで、基本的な浮動小数点演算機能を提供します。
  • VFPv3: VFPv1の改良版で、より多くの浮動小数点レジスタ(通常32個の単精度レジスタ)と、より効率的な命令セットを提供します。これにより、浮動小数点演算を多用するアプリケーションのパフォーマンスが大幅に向上します。

Native Client (NaCl)

Native Client(NaCl)は、Googleが開発したオープンソースのサンドボックス技術で、ウェブブラウザ内でC/C++などのネイティブコードを安全かつポータブルに実行することを可能にします。NaClは、ウェブアプリケーションがネイティブコードのパフォーマンスを活用できるように設計されましたが、WebAssemblyの登場により、現在では非推奨となっています。

このコミットが作成された2014年当時は、NaClはまだ活発に開発されており、Go言語もNaClをターゲットとしてサポートしていました。NaCl環境は、特定のハードウェア特性(この場合はARMプロセッサのVFPv3サポート)を保証できる場合がありました。

cmd/dist

cmd/distは、Go言語のソースコードからGoツールチェイン(コンパイラ、リンカ、アセンブラなど)自体をビルドするために使用されるツールです。Goのソースコードをダウンロードしてall.bash(Unix系)やall.bat(Windows系)を実行すると、このcmd/distが起動し、Goのビルドプロセス全体を管理します。cmd/distは、ターゲットとなるOSやアーキテクチャに応じて、適切なビルド設定や環境変数を決定する役割も担っています。

技術的詳細

このコミットで変更されたsrc/cmd/dist/arm.cファイルは、cmd/distツールの一部であり、ARMアーキテクチャ向けのビルド設定、特にGOARM環境変数の値を決定するロジックを含んでいます。

変更前のxgetgoarm関数は、xtryexecfunc(useVFPv3)という関数呼び出しを通じて、実行時にVFPv3のサポートを検出していました。この検出は、特定のテストコードを実行してFPUの機能を検証する形で行われていたと考えられます。

しかし、nacl環境においては、VFPv3のサポートが常に存在することが既知の事実でした。そのため、動的な検出は不要であり、場合によっては検出ロジックが誤った結果を返すか、不必要なオーバーヘッドを発生させる可能性がありました。

このコミットでは、以下の変更が加えられました。

-\tif(xtryexecfunc(useVFPv3))\n+\t// NaCl always has VFP support.\n+\tif(streq(goos, \"nacl\") || xtryexecfunc(useVFPv3))\n```

この変更により、`xgetgoarm`関数は、まずターゲットOSが`nacl`であるかどうかを`streq(goos, "nacl")`でチェックします。

*   もし`goos`(GoのターゲットOS)が`"nacl"`であれば、`xtryexecfunc(useVFPv3)`の呼び出しをスキップし、無条件に`GOARM=7`を返します。これは、`nacl`環境ではVFPv3サポートが保証されているため、検出が不要であることを意味します。
*   もし`goos`が`"nacl"`でなければ、従来のロジック通り`xtryexecfunc(useVFPv3)`を呼び出してVFPv3のサポートを検出し、その結果に基づいて`GOARM`の値を決定します。

この変更は、`nacl/arm`ターゲットに特化した最適化であり、ビルドプロセスの効率化と、生成されるバイナリの性能保証に貢献します。

## コアとなるコードの変更箇所

```diff
--- a/src/cmd/dist/arm.c
+++ b/src/cmd/dist/arm.c
@@ -21,7 +21,8 @@ xgetgoarm(void)\
 	// FreeBSD has broken VFP support
 	return "5";
 #endif
-\tif(xtryexecfunc(useVFPv3))\n+\t// NaCl always has VFP support.\n+\tif(streq(goos, \"nacl\") || xtryexecfunc(useVFPv3))\n \t\treturn \"7\";\
 \telse if(xtryexecfunc(useVFPv1))\
 \t\treturn \"6\";\

コアとなるコードの解説

変更はsrc/cmd/dist/arm.cファイルのxgetgoarm関数内で行われています。この関数は、GoのビルドシステムがARMアーキテクチャ向けのGOARM環境変数の値を決定するために使用されます。

元のコードでは、以下の条件文がありました。 if(xtryexecfunc(useVFPv3))

これは、useVFPv3という機能が利用可能かどうかをxtryexecfuncというヘルパー関数を使って動的にチェックしていました。もしVFPv3が利用可能であれば、"7"GOARM=7)を返していました。

変更後のコードは以下のようになります。 // NaCl always has VFP support. if(streq(goos, "nacl") || xtryexecfunc(useVFPv3))

この変更のポイントは、streq(goos, "nacl")という条件が追加されたことです。

  • streq(goos, "nacl"): これは、現在のターゲットオペレーティングシステム(goos)が文字列"nacl"と等しいかどうかをチェックします。
  • ||: 論理OR演算子です。

したがって、新しい条件文は「もしターゲットOSがnaclであるか、またはxtryexecfunc(useVFPv3)が真(VFPv3が検出された)であるならば」という意味になります。

これにより、nacl環境でビルドする際には、xtryexecfunc(useVFPv3)による動的なVFPv3検出をスキップし、無条件にGOARM=7が適用されるようになりました。これは、nacl環境ではVFPv3のサポートが常に保証されているという前提に基づいています。この変更によって、nacl/arm向けのビルドがより効率的かつ正確に行われるようになります。

関連リンク

  • Go言語の公式ドキュメント(GOARMに関する情報が含まれる可能性があります)
  • Google Native Client (NaCl) の公式情報(現在はWebAssemblyに移行しているため、アーカイブ情報となる可能性が高いです)
  • ARMアーキテクチャのVFPに関する技術資料

参考にした情報源リンク

# [インデックス 19714] ファイルの概要

## コミット

commit 366f88f3e4449c609f3a5310c79536cfcd22f5c2 Author: Shenghou Ma minux@golang.org Date: Thu Jul 10 15:15:24 2014 -0400

cmd/dist: always use GOARM=7 for nacl/arm

LGTM=dave, rsc
R=rsc, iant, dave
CC=golang-codereviews
https://golang.org/cl/101590044

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/366f88f3e4449c609f3a5310c79536cfcd22f5c2](https://github.com/golang/go/commit/366f88f3e4449c609f3a5310c79536cfcd22f5c2)

## 元コミット内容

`cmd/dist: always use GOARM=7 for nacl/arm`

このコミットは、Goのビルドツールである`cmd/dist`において、`nacl/arm`(Native Client on ARM)ターゲット向けにビルドする際に、常に`GOARM=7`を使用するように変更するものです。

## 変更の背景

Go言語は、様々なアーキテクチャとオペレーティングシステムをサポートしています。ARMアーキテクチャは、モバイルデバイスや組み込みシステムで広く利用されており、その中で浮動小数点演算ユニット(FPU)のバージョンが複数存在します。Goのビルドシステムは、ターゲットとなるARMプロセッサのFPUの能力に応じて、最適なコードを生成するために`GOARM`環境変数を使用します。

以前の`cmd/dist`のロジックでは、ARMターゲットのFPUサポートを動的に検出していました。しかし、`nacl/arm`(Google Native Client for ARM)の場合、特定の環境下ではVFPv3(Vector Floating Point version 3)のサポートが常に保証されていました。従来の検出ロジックでは、この`nacl`環境の特性が十分に考慮されておらず、場合によってはVFPv3をサポートしているにもかかわらず、より古いFPUバージョン(例えばVFPv1)向けのコードが生成されてしまう可能性がありました。

このコミットは、`nacl/arm`環境ではVFPv3サポートが確実であるという前提に基づき、検出ロジックをスキップして直接`GOARM=7`(VFPv3を意味する)を設定することで、`nacl/arm`向けのGoバイナリが常に最適な浮動小数点演算性能を発揮できるようにすることを目的としています。これにより、`nacl/arm`上でのGoアプリケーションのパフォーマンス向上と、ビルドの信頼性向上が期待されます。

## 前提知識の解説

### GOARM環境変数

`GOARM`はGo言語のビルドシステムで使用される環境変数で、ARMアーキテクチャ向けのコンパイル時に、ターゲットとなるARMプロセッサの浮動小数点演算ユニット(FPU)のバージョンを指定します。

*   **`GOARM=5`**: ARMv5アーキテクチャ向け。ハードウェア浮動小数点演算ユニットがないか、使用しない設定で、ソフトウェアによる浮動小数点演算が行われます。
*   **`GOARM=6`**: ARMv6アーキテクチャ向け。VFPv1(Vector Floating Point version 1)をサポートするハードウェア浮動小数点演算ユニットを使用します。
*   **`GOARM=7`**: ARMv7アーキテクチャ以降向け。VFPv3(Vector Floating Point version 3)をサポートするハードウェア浮動小数点演算ユニットを使用します。VFPv3はVFPv1よりも多くのレジスタと命令セットを持ち、より高性能な浮動小数点演算が可能です。

### VFP (Vector Floating Point)

VFPは、ARMアーキテクチャのプロセッサに搭載される浮動小数点演算ユニット(FPU)の名称です。VFPは、単精度および倍精度の浮動小数点演算をハードウェアで高速に実行するために設計されています。

*   **VFPv1**: 初期バージョンのVFPで、基本的な浮動小数点演算機能を提供します。
*   **VFPv3**: VFPv1の改良版で、より多くの浮動小数点レジスタ(通常32個の単精度レジスタ)と、より効率的な命令セットを提供します。これにより、浮動小数点演算を多用するアプリケーションのパフォーマンスが大幅に向上します。

### Native Client (NaCl)

Native Client(NaCl)は、Googleが開発したオープンソースのサンドボックス技術で、ウェブブラウザ内でC/C++などのネイティブコードを安全かつポータブルに実行することを可能にします。NaClは、ウェブアプリケーションがネイティブコードのパフォーマンスを活用できるように設計されましたが、WebAssemblyの登場により、現在では非推奨となっています。

このコミットが作成された2014年当時は、NaClはまだ活発に開発されており、Go言語もNaClをターゲットとしてサポートしていました。NaCl環境は、特定のハードウェア特性(この場合はARMプロセッサのVFPv3サポート)を保証できる場合がありました。

### cmd/dist

`cmd/dist`は、Go言語のソースコードからGoツールチェイン(コンパイラ、リンカ、アセンブラなど)自体をビルドするために使用されるツールです。Goのソースコードをダウンロードして`all.bash`(Unix系)や`all.bat`(Windows系)を実行すると、この`cmd/dist`が起動し、Goのビルドプロセス全体を管理します。`cmd/dist`は、ターゲットとなるOSやアーキテクチャに応じて、適切なビルド設定や環境変数を決定する役割も担っています。

## 技術的詳細

このコミットで変更された`src/cmd/dist/arm.c`ファイルは、`cmd/dist`ツールの一部であり、ARMアーキテクチャ向けのビルド設定、特に`GOARM`環境変数の値を決定するロジックを含んでいます。

変更前の`xgetgoarm`関数は、`xtryexecfunc(useVFPv3)`という関数呼び出しを通じて、実行時にVFPv3のサポートを検出していました。この検出は、特定のテストコードを実行してFPUの機能を検証する形で行われていたと考えられます。

しかし、`nacl`環境においては、VFPv3のサポートが常に存在することが既知の事実でした。そのため、動的な検出は不要であり、場合によっては検出ロジックが誤った結果を返すか、不必要なオーバーヘッドを発生させる可能性がありました。

このコミットでは、以下の変更が加えられました。

```c
-\tif(xtryexecfunc(useVFPv3))\n+\t// NaCl always has VFP support.\n+\tif(streq(goos, \"nacl\") || xtryexecfunc(useVFPv3))\n```

この変更により、`xgetgoarm`関数は、まずターゲットOSが`nacl`であるかどうかを`streq(goos, "nacl")`でチェックします。

*   もし`goos`(GoのターゲットOS)が`"nacl"`であれば、`xtryexecfunc(useVFPv3)`の呼び出しをスキップし、無条件に`GOARM=7`を返します。これは、`nacl`環境ではVFPv3サポートが保証されているため、検出が不要であることを意味します。
*   もし`goos`が`"nacl"`でなければ、従来のロジック通り`xtryexecfunc(useVFPv3)`を呼び出してVFPv3のサポートを検出し、その結果に基づいて`GOARM`の値を決定します。

この変更は、`nacl/arm`ターゲットに特化した最適化であり、ビルドプロセスの効率化と、生成されるバイナリの性能保証に貢献します。

## コアとなるコードの変更箇所

```diff
--- a/src/cmd/dist/arm.c
+++ b/src/cmd/dist/arm.c
@@ -21,7 +21,8 @@ xgetgoarm(void)\
 	// FreeBSD has broken VFP support
 	return "5";
 #endif
-\tif(xtryexecfunc(useVFPv3))\n+\t// NaCl always has VFP support.\n+\tif(streq(goos, \"nacl\") || xtryexecfunc(useVFPv3))\n \t\treturn \"7\";\
 \telse if(xtryexecfunc(useVFPv1))\
 \t\treturn \"6\";\

コアとなるコードの解説

変更はsrc/cmd/dist/arm.cファイルのxgetgoarm関数内で行われています。この関数は、GoのビルドシステムがARMアーキテクチャ向けのGOARM環境変数の値を決定するために使用されます。

元のコードでは、以下の条件文がありました。 if(xtryexecfunc(useVFPv3))

これは、useVFPv3という機能が利用可能かどうかをxtryexecfuncというヘルパー関数を使って動的にチェックしていました。もしVFPv3が利用可能であれば、"7"GOARM=7)を返していました。

変更後のコードは以下のようになります。 // NaCl always has VFP support. if(streq(goos, "nacl") || xtryexecfunc(useVFPv3))

この変更のポイントは、streq(goos, "nacl")という条件が追加されたことです。

  • streq(goos, "nacl"): これは、現在のターゲットオペレーティングシステム(goos)が文字列"nacl"と等しいかどうかをチェックします。
  • ||: 論理OR演算子です。

したがって、新しい条件文は「もしターゲットOSがnaclであるか、またはxtryexecfunc(useVFPv3)が真(VFPv3が検出された)であるならば」という意味になります。

これにより、nacl環境でビルドする際には、xtryexecfunc(useVFPv3)による動的なVFPv3検出をスキップし、無条件にGOARM=7が適用されるようになりました。これは、nacl環境ではVFPv3のサポートが常に保証されているという前提に基づいています。この変更によって、nacl/arm向けのビルドがより効率的かつ正確に行われるようになります。

関連リンク

  • Go言語の公式ドキュメント(GOARMに関する情報が含まれる可能性があります)
  • Google Native Client (NaCl) の公式情報(現在はWebAssemblyに移行しているため、アーカイブ情報となる可能性が高いです)
  • ARMアーキテクチャのVFPに関する技術資料

参考にした情報源リンク