
プログラミング
イベント
マガジン
技術ブログ
こんにちは、QAコンサルタントのヤマダです。 ソフトウェア開発の現場では、日々、品質の確保、生産性の向上、そして技術の継承といった課題に直面します。経験豊富なエースエンジニアの活躍で一時的に問題が解決されても、そのノウハウがチームに共有されなければ、同じ問題が繰り返し発生してしまいます。 こうした「属人化」という名の落とし穴を避け、チームとして継続的に成長していくために不可欠なのが 「標準」 という考え方です。 「標準」と聞くと「形式的で堅苦しい」「創造性を縛るもの」といったネガティブなイメージを持つ方がいるかもしれません。しかし、標準は開発現場を混乱から救い、より高品質なソフトウェアを、より効率的に生み出すための強力な「羅針盤」となり得ます。 この記事では、まず「標準」そのものについて深く掘り下げ、具体的な事例を交えながら、標準を形骸化させずに「生きた資産」として育て続けるためのアプローチについて解説していきます。 そもそも「標準」とは何か? 「標準」には、その成り立ちや適用範囲によっていくつかの種類があります。大きくは、公的な機関が定めたものと、市場で事実上標準と見なされるようになったものに分けられます。 デジュールスタンダード (de jure standard) 国際標準化機構(ISO)や日本産業規格(JIS)といった公的な標準化団体によって策定・発行された、公式な規格です。「法律上の」といった意味を持ちます。 デファクトスタンダード (de facto standard) 公的な機関が定めたものではなくても、市場での競争や業界の支持によって広く普及し、事実上の標準として機能しているものです。「事実上の」という意味を持ちます。 しかし、私たちが現場で意識すべき「標準」は、これだけではありません。チーム内で定められた コーディング規約 、プロジェクトで共通して使われる 設計書のテンプレート 、 Gitのブランチ戦略 といったものも、私たちを日々の迷いから救ってくれる重要な「現場の標準」なのです。 ソフトウェア開発に関連する「標準」のランドスケープ では、具体的にどのような標準が存在するのでしょうか。ここでは代表的なものを「デジュール」と「デファクト」に分類してご紹介します。 デジュールスタンダード (公的標準) 国際的な合意形成に基づいているため信頼性が高く、認証制度と結びついているものも多くあります。 標準/規格名 発行元 概要 ISO 9001 ISO 品質マネジメントシステム の国際規格。製品・サービスの品質保証の仕組みを構築・運用するための要求事項を定めています。 ISO 21502 ISO プロジェクトマネジメント の手引に関する国際規格。デファクトスタンダードであるPMBOK®ガイドなど世界中の知見を基に策定されました。PMBOK®が詳細なツールや技法(How)を含むのに対し、本規格は組織が従うべきハイレベルな概念やプロセス(What)を定義するガイダンスであり、相互補完的な関係にあります。 ISO/IEC 25000 (SQuaRE) ISO/IEC ソフトウェア品質 に関する国際規格群。ソフトウェアの品質モデルを定義し、その測定と評価の方法を規定しています。 ISO/IEC/IEEE 12207 ISO/IEC/IEEE ソフトウェアライフサイクルプロセス の国際規格。ソフトウェアの企画から開発、保守、廃棄までの一連のプロセスを定義しています。 ISO/IEC/IEEE 29119 ISO/IEC/IEEE ソフトウェアテスト に関する国際規格シリーズ。テストプロセス、テストドキュメント、テスト技法、キーワード駆動テストなど、テストに関する包括的な内容を扱います。 ISO/IEC 27001 ISO/IEC 情報セキュリティマネジメントシステム (ISMS) の国際規格。情報資産を保護するための管理策を体系的に示しています。 デファクトスタンダード (事実上の標準) 技術の進化に迅速に対応しやすく、特定の分野で強い影響力を持つものが多くあります。 標準/規格名 発行元/管理者 概要 PMBOK®ガイド PMI プロジェクトマネジメント の知識体系。公的規格であるISO 21502の策定にも大きな影響を与えた、業界で最も広く参照されるガイドラインの一つです。 CMMI® ISACA 組織の プロセス成熟度 を5段階で評価・改善するためのモデル。元々は米国カーネギーメロン大学(SEI)で開発され、現在はISACAが引き継いで維持・管理しています。 ITIL® AXELOS ITサービスマネジメント におけるベストプラクティス集。多くの企業のIT部門で運用管理の指針として採用されています。 OWASP Top 10 OWASP Webアプリケーションのセキュリティ に関する最も重大な10のリスクをまとめたレポート。セキュリティ対策の基準として広く参照されます。 【事例】標準を知らないと、実績のあるベテランでも大怪我をする ここで、標準の重要性を実感していただくために、ある現場で実際に起きた 「実績のあるベテランが、標準を知らなかったために大失敗してしまった」 苦い事例をご紹介します。 ある小規模な医療系システムの開発プロジェクトに、開発歴20年で数々の修羅場をくぐり抜けてきたエンジニアのAさんが助っ人として参画しました。Aさんは技術力も高く、過去の経験をもとに独自の「秘伝のタレ」のような効率的なテスト方針を組み立て、 圧倒的なスピードと手際の良さ で次々とテストを消化していきました。チーム全員が「さすがAさんだ」と安心していました。 しかし、プロジェクトの最終盤、クライアントである大手医療機器メーカーによる 品質レビュー が入ったときに事件は起きました。 先方の担当者から 「国際規格である『ISO/IEC/IEEE 29119』に準拠したテスト成果物(ドキュメント)を見せてください」 と求められたのです。 Aさんは「独自の効率的なやり方」でテストを進めていたため、国際規格が求めるプロセス(どのような根拠でそのテスト技法を選び、どう成果物を残すべきか)を満たしていませんでした。Aさんにとっては「十分にテストした」という自信がありましたが、先方からは 「国際規格(標準)を満たしていないため、品質が客観的に証明されていない」 という最悪の評価を下されてしまったのです。 結果として、膨大なテストのやり直しとドキュメントの再作成が発生し、プロジェクトのリリースは数ヶ月延期。Aさんのプライドも、チームの信頼も大きく傷つく結果となってしまいました。 Aさんの技術力や熱意は本物でした。しかし、 「世界中の知見が集まった『標準』を知ろうとしなかったこと」 が失敗の原因でした。 どれだけ実績のあるベテランであっても、自分の「経験則」だけで標準という「集合知」に勝つことは難しいのです。 なぜ私たちは「標準」を活用すべきなのか? Aさんの事例からも分かるように、標準とは単なる堅苦しいルールではなく、先人たちが同じような失敗を重ねた末にたどり着いた「これさえ守れば絶対に大怪我をしない」という防御壁(ベストプラクティス)です。これらを適切に活用することは、開発チームに計り知れないメリットをもたらします。 品質の安定と向上: 先人たちの知見に基づき、担当者のスキルに依存しない一定の品質レベルを客観的に確保・証明します。 生産性の向上: 「車輪の再発明」や「プロセスの独りよがり」を避け、開発者がより本質的な課題解決に集中できるようにします。 コミュニケーションコストの削減: 「共通言語」を持つことで、組織内外との認識の齟齬や無駄な手戻りを減らします。 技術の伝承と人材育成: 標準化されたドキュメントは、新メンバーや次世代のエンジニアにとって最高の「教科書」となります。 「標準」を育てる:知識創造のアプローチ「SECIモデル」 標準を導入しても、それが形骸化しては意味がありません。また、先ほどのAさんのように外から与えられた標準に振り回されるだけでなく、自らの知見を標準へと昇華させ、チームの資産として育てていくことが重要です。 標準の改善というと、多くの方が品質管理の基本である 「PDCAサイクル」 を思い浮かべるかもしれません。確かに、 既存の標準をより効率的に、 より安定させる といった「改善」のフェーズにおいてPDCAは非常に有効です。 しかし、「エースエンジニアのノウハウ」のような まだ形になっていない知恵を標準化する 、つまり 「創造」 のフェーズではどうでしょうか。この「0→1」を生み出すプロセスで特に力を発揮するのが、知識創造のフレームワークである 「SECIモデル」 です。 SECIモデルは、個人の「暗黙知(経験や勘)」を、組織の「形式知(=標準)」へと昇華させていく4つのプロセスから成ります。ここからは、別のチームの成功事例を追いながら、そのプロセスを見ていきましょう。 【事例】開発チームが「無敵のエース依存」から脱却した話 新機能の開発を進めていた開発チームには、セキュリティ実装にめっぽう強いエースエンジニアのBさんがいました。Bさんが担当する機能は常に堅牢でバグもありません。しかし、Bさんが他の重要案件で手一杯になると、チーム全体の開発スピードがガクンと落ち、他のメンバーが書いたコードにはセキュリティ上の指摘が多発するという「属人化」の課題を抱えていました。 そこでチームは、Bさんの頭の中にあるノウハウを「標準」に変えるため、SECIモデルに沿った取り組みを行いました。 共同化 (Socialization) – 暗黙知から暗黙知へ まずは若手メンバーがBさんとペアプログラミングを行い、Bさんがコードを書く際に見ているポイントや「なんとなく怪しい」と感じる勘所を対話を通じて肌で学びました。SECIモデルは、PDCAのように明確な「計画」からではなく、こうした現場での自然な知識共有から始まります。 表出化 (Externalization) – 暗黙知から形式知へ ペアプロで得た知見をもとに、Webアプリケーションで特に注意すべき脆弱性対策を誰もが理解できる形に言語化・図解化し、5項目の簡易的な「セキュリティレビュー・チェックリスト」を作成しました。ここで初めて、組織の資産としての「標準 Ver. 1.0」が誕生します。 連結化 (Combination) – 形式知から形式知へ 生まれたばかりのチェックリストを、チームが元々持っていた「Gitブランチ運用ルール」や「コードレビュー方針」のドキュメントと組み合わせ、より体系的な開発フローのガイドラインへと発展させました。 内面化 (Internalization) – 形式知から暗黙知へ 体系化された標準をメンバーが毎回のプルリクエストで実践しました。繰り返すうちに、意識せずともセキュアなコードが書けるようになり、メンバー全体の新たなスキル(暗黙知)として体得されました。 SECIモデルとPDCAサイクルの融合 この開発チームの取り組みには、さらに続きがあります。 作成したチェックリストを運用していく中で、チームは業界のデファクトスタンダードである 「OWASP Top 10」 の存在を知りました。そこで、自分たちの標準(Ver. 1.0)とOWASP Top 10を見比べ、「あ、この視点が抜けていたね」と気づき、 PDCAサイクルを回して標準をさらにアップデート(Ver. 2.0へ) していったのです。 このように、SECIモデルは特に、属人化しがちなノウハウを組織の力に変えるための新しい標準を生み出すプロセスとして非常に有効です。そして、SECIモデルによって生み出された「標準 Ver. 1.0」を、今度は日々の運用の中でPDCAサイクルを回して「Ver. 1.1、 1.2」へと磨き上げていく。 このように両者を組み合わせることで、組織は創造と改善の両輪を手に入れることができるのです。 まとめ ソフトウェア開発における「標準」は、デジュール、デファクトといった公的なものから、現場のテンプレートまで多岐にわたります。これらを単に導入するだけでなく、チームの資産として育てていくことが重要です。 個人の経験則だけで突っ走ると、世界の標準に通用せず思わぬ大怪我をすることがあります(Aさんの例)。一方で、エースの持つ優れたノウハウを SECIモデル で組織の「標準」へと昇華させ、それを PDCAサイクル で磨き上げ続ければ、チーム全体の力が底上げされます(Bさんの例)。 標準は私たちを縛るものではなく、無駄な作業や致命的な失敗から解放し、より本質的な仕事へと導いてくれる強力なパートナーです。創造と改善のサイクルを回しながら、チームの力を最大限に引き出す「生きた標準」を育てていきましょう。 The post なぜ、車輪の再発明をやめるべきなのか? ソフトウェア開発における「標準」の本当の価値 first appeared on Sqripts .
Go Conference 2026 目次 はじめに エブリーのスポンサーブース アンケートボード 食クイズ・くじ引き ノベルティ セッション紹介 Go における FFI のこれまでとこれから cgo とその課題 WebAssembly を使った FFI wasmify と wasm2go 感想 ワークショップ紹介 go.devの歩き方、その先へ 〜Go公式リソースの旅。明日からの調べ方を手に入れるワークショップ〜 参加した理由 ワークショップの流れ 設問2 の調査 ワークショップで得たこと Go × SIMDで高速化するベクトル検索 ~ ルーフラインモデルでSIMDが効く境界を探れ! SIMDとは GoからSIMDを使う ベンチマークで効果を確認する int8量子化でデータ量を減らす ワークショップを体験して まとめ 非公式アフターイベント Go BASH Vol.3 のお知らせ 最後に はじめに 2026年9月11日(金)に中野セントラルパークで開催された「Go Conference 2026」に今年も参加させていただきました! 今年も参加レポートとして、会場の様子やセッションの感想についてお届けします! gocon.jp 今年のテーマは「 Go Far, Go Together 」でした。 Go Far, Go Together このテーマの通り、人との繋がりを重要視していることが強く感じられるカンファレンスだったと思います。 sanposhiho さんのKeynoteセッション「Open Source, Open World」に始まり、 speakerdeck.com コミュニケーションスペースのGo Context Wall、伝Go板、スポンサーブース、難易度別セッション・ワークショップ、そして最後は懇親会と、Goを始めたての人でも、熟練の方でも最初から最後まで楽しめたカンファレンスだったのではないかなと思います。 エブリーのスポンサーブース エブリーは今年は Silver スポンサーとしてブースを出展させていただきました! 弊社サービスであるデリッシュキッチンをイメージした黄色基調のブースとなっています。 エブリーブース ブースに足を運んでいただいた皆様、本当にありがとうございました! アンケートボード 昨年に引き続きアンケートボードを用意しました! 「あなたのGo興味教えてください」というテーマで、Go歴 (Goの利用歴)と気になるトピックが交わる場所にシールを貼っていただきました。 最終結果はこちらです! アンケート結果 Go歴0〜15年以上の方まで幅広いGopherに回答いただきましたが、Go歴0〜1年の方は設計思想、ある程度経験のある方は最新のGo1.27のトピックに関心が若干寄っているところが面白い部分でした。 またどのGo歴の方もGoとAIに対して関心があり、どんなAI Agentが社内で使われているのか、またどのようにHarnessを作っているのかといった話題についてブースではたくさんお話しすることができました! 食クイズ・くじ引き 今年から導入した新しいブース企画である、クイズも非常に盛り上がりました! クイズは食に関する問題2問、Goに関する問題2問の計4問で構成されています。 最終問題のGoの実行結果を答えるクイズで、言語仕様を理解していないと解けなかったり、考えたことがなかったユースケースに対して回答する必要があったりと、難しめに設定しただけあって苦戦している参加者の方も多く見られました。 クイズ ノベルティ 景品は軽量スプーン、まな板、菜箸、しゃもじなど普段の料理で使えるキッチングッズです。 デリッシュキッチングッズ ハズレを引いた方にも、弊社CTOが自らテイスティングして選んだ「CTOブレンド」のコーヒーとステッカーをお渡ししました。 CTOブレンド CTOブレンドの制作秘話については下記を参照ください。 人々へ明るい変化を提供する、オリジナルブレンドコーヒー「every CTO Blend」を制作 キッチングッズが当たった方からは、「最近自炊を始めたのでこれを使って頑張ります」といった感想や、「まさに今欲しかったものなので嬉しいです」といった感想をいただけて運営としても嬉しかったです! また、このくじ引きで当選したまな板を今でも使っているという方もいたりと、何度もイベントに出展しているとこういうこともあるのかと嬉しくなりました。 セッション紹介 Go における FFI のこれまでとこれから 発表者: goccy さん(株式会社LayerX) レポート: あかがわまさとも スライド: speakerdeck.com 食事管理アプリ ヘルシカ を担当している あかがわまさとも です。私からは、goccy さんの発表「Go における FFI のこれまでとこれから」について紹介させていただきます。 FFI(Foreign Function Interface)は、同一プロセス内で、ある言語で書かれたプログラムから他の言語で実装された機能を呼び出すための仕組みです。本セッションでは、従来の cgo を使う方法とそれに対する課題から、goccy さんによる WebAssembly を活用した新しい方法までを紹介していただきました。 cgo とその課題 スライド 3〜15 ページ FFI での呼び出しは、ABI(Application Binary Interface)という「バイナリ間で関数を呼び出すための約束」に合わせて行う必要があります。Go では、この ABI に合わせた呼び出しを cgo が引き受けています。 発表の序盤では、cgo が抱える課題が3つの観点から整理されていました。 メモリ管理 : Go と C ではメモリの管理が分かれているためメモリリークが起きやすく、C 側でセグメンテーション違反(SIGSEGV)が起きると Go のプロセスごと落ちます。さらに両者はアドレス空間を共有しているので、C 側の不具合で Go 側のメモリを読み書きできてしまいます。 型変換 : 構造体へのポインタや、コールバックのための関数ポインタの受け渡しが複雑になります。相手が C++ だとさらに難しくなります。 開発・デプロイ : C コンパイラが必要になるため Go のクロスコンパイルの手軽さが失われ、Go のプロファイラやデバッガも C 側のコードには使えません。 そのうえで、ポインタのライフサイクル管理、コールバックの実装、静的リンクによるシングルバイナリ化という3つのテクニックが紹介されました。ただしこれらは対症療法で、メモリの管理が分かれていることや C コンパイラが必要になることは、cgo を使う限り変わりません。 普段は Go だけで完結する開発をしているので cgo を書く機会は全くないのですが、課題を詳しく紹介していただき、あまり活用されていない現状や難しさにかなり納得しました。 WebAssembly を使った FFI スライド 16〜23 ページ ここまでの課題を踏まえて、「メモリを安全に扱いたい」「Go のクロスコンパイルの恩恵を受けたい」という動機から WebAssembly(WASM)を使う方法が紹介されました。 WASM モジュールは、自分専用に割り当てられた連続したメモリ領域(リニアメモリ)しか読み書きできないため、ホストとアドレス空間が完全に分離されます。範囲外アクセスはプロセスのクラッシュではなく Go のエラーになります。システムコールも、ホストが許可したものだけが WASI 経由で実行されます。WASI は WebAssembly System Interface の略で、WASM からファイルやネットワークといったホスト側の機能を使うための標準インターフェースです。Go 側は WASM を embed で埋め込み、Pure Go のランタイムである wazero で実行するので、先ほどの課題の多くはここで解消されます。 ただし、C/C++ プロジェクトから WASM を作ること自体が難しく、アドレス空間の異なるホストとのブリッジを書くのも簡単ではありません。cgo なら文字列のアドレスと長さを渡すだけで済むところが、WASM ではリニアメモリ上に領域を確保し、そこにホスト側から書き込む必要があります。安全のために境界を引いた分、その境界をまたぐコードは自分で書くことになります。 wasmify と wasm2go スライド 24〜50 ページ 発表の後半は、この境界を越える手間を減らすために goccy さんが開発したツールの話でした。 wasmify は、C/C++ ライブラリから FFI 用途の WASM とブリッジコードを生成する手順を抽象化した、AI エージェントのハーネスとして利用できるツールです。プロジェクトごとに大きく異なるビルド手順の部分は AI に吸収してもらい、正規化した設定をファイルに残すことで、CI などでは AI なしで同じ結果を再現できるようにしています。非決定的な部分だけを AI に任せ、その結果を固定して冪等性を担保するという設計は、FFI に限らず AI を開発に組み込むときの考え方として参考になりました。 ところが、wasmify で作り直した Pure Go 版の bigquery-emulator(BigQuery のローカルエミュレータ)については、リリースの翌日からパフォーマンス低下の報告が相次いだそうです。あるケースでは 0.6 秒だった処理が 17.3 秒と、約30分の1の速度になっていたとのことでした。この問題への対処として開発されたのが wasm2go で、WASM を Go と Plan9 asm に変換してしまうというアプローチです。メモリが分離されているという WASM の性質は保ったまま、変換後は WASM 由来の実行時の制限を受けないため、最適化の余地が生まれます。 しかし、wasm2go にも課題はありました。たとえば、変換後の Go コードが巨大になるため、そのままではメモリ不足でコンパイルが通らなくなってしまいます。これに対しては、コンパイルの単位を分けて依存関係を直列にし、そこで生じる循環参照を go:linkname で回避するという解決策が取られていました。 go:linkname は、呼びたい関数が定義されている package を import せずにその関数を参照できるコンパイラディレクティブです。ほかの課題への対処も含め、どれも Go の処理系やツールチェーンの挙動を踏まえた解き方で、ここは聞いていて一番面白かったです。 最後に、wasm2go の成果物として go-googlesql や go-python、go-llama といった Pure Go 実装が公開されており、これらを Go から組み合わせて呼び出す Cross Language Binding や、Go のための Agent Sandbox といった応用先も紹介されました。 感想 goccy さんはほぼ毎回 go:linkname の話をされているそうです。発表の本筋ではないですが、今回も後半で循環参照の解消の文脈で登場しました。初めて goccy さんの発表を聞く機会を頂いたのは、今年2月の Go Conference mini in Sendai 2026 でしたが、当時は何のことか分からず困惑した状態で聞いたのを覚えています。 speakerdeck.com 今回はこの go:linkname が何かを知った状態で臨むことができたので、前回よりも楽しく拝聴させていただきました。人の話を聞いて知るきっかけをもらい、前よりも技術を楽しめるようになって、またそこで知らないことを知る。この繰り返しが起きるのが、カンファレンスという場所の素敵なところだなと思います。 goccy さん、興味深い発表をありがとうございました!そして、エブリーブースにも来ていただきありがとうございました!直接感想を伝えられて嬉しかったです! ワークショップ紹介 go.devの歩き方、その先へ 〜Go公式リソースの旅。明日からの調べ方を手に入れるワークショップ〜 講師: Koki Narumi さん(ANDPAD) レポート: 野村 こんにちは。開発1部でデリッシュキッチンのプレミアム機能を開発している新卒エンジニアの 野村 です。 私はワークショップ「go.devの歩き方、その先へ」に参加しました。 参加した理由 Go 歴は 4 ヶ月ほどです。 Go でわからないことがあったとき、AI に聞いて済ませることもできますが、自分の手で調べた方が理解は深まると感じていました。 AI の回答が間違っている可能性を頭に置きながら進めたり、その回答が正しいかを確かめたりするためにも、公式ドキュメントを調べる力があった方がよいと考えて参加しました。 ベテランの方々が公式ドキュメントをどのように読んでいるのかにも興味がありました。 ワークショップの流れ 当日は andpad-dev/gotan リポジトリの教材に沿って、次の流れで進みました。 リポジトリの説明 初級、中級、上級のレベルごとに分かれて 4 人の班を組む 班ごとに GitHub の Issue を 1 つ持ち、そこに自己紹介を書き込む 班でカテゴリとテーマを選ぶ 設問ごとに 2 人に分かれて調査し、調査結果を Issue に書き込んでいく 答え合わせ 私は Go 歴が浅いので初級を選びました。 カテゴリは次の 4 つから選びます。 Go の標準パッケージ Go の機能や文法構造 Go のコマンド Go の言語仕様、標準ライブラリの実装、設計の背景 私たちの班は「Go のコマンド」を選びました。 初級には 3 つのテーマがあり、その中から go run のテーマ を選びました。 テーマには設問が 3 つあり、私は設問2「go run でビルドされた実行ファイルや $WORK ディレクトリは、実行後どうなるか」を担当しました。 各設問にはヒントと答えが用意されていて、必要になったときに読める形になっています。 設問2 の調査 ここでは、設問2 をどう調べていったかを紹介します。 設問1と設問2はつながっているので、まず設問1にも目を通しました。 最初は手がかりがなかったため、答えに近づきすぎないようにヒントをざっと眺め、そこに書かれていたコマンドをまず実行してみることにしました。 go run -a -x main.go 2 > first.log この -a と -x が何をするフラグなのかを調べました。 調べ方は 03-cmd-tools の README にガイドがあり、それを見ながら進めました。 go help build でも読めますが、今回は pkg.go.dev/cmd/go をページ内検索して確かめました。 -a : すでに最新状態にあるパッケージも強制的に再ビルドする -x : 実行するコマンドを表示する first.log を開くと、1 行目に $WORK ディレクトリのパスが書かれていました。 WORK=/var/folders/bj/1bpczlgx0nxd7gyh6k1gxnhm0000gp/T/go-build2456729570 ここで $WORK に移動しようとしましたが、このディレクトリはすでに存在しませんでした。 cd: no such file or directory: /var/folders/bj/1bpczlgx0nxd7gyh6k1gxnhm0000gp/T/go-build2456729570 first.log の末尾を見ると、実行ファイルを cp している行があったので、そのコピー先に移動してみました( 班の調査ログ )。 cp $WORK/b001/exe/main /Users/yuto.nomura/Library/Caches/go-build/96/9677dc4b2f735a2ab8ac9be91e1f1c1ce061dcd1e81e39106ac0b016771e252e-d/main # internal $WORK/b001/exe/main コピー先には main の実行ファイルが残っていました。 つまり $WORK ディレクトリは削除されているが、実行ファイルはキャッシュとして残っている、ということになります。 次に、手詰まりだったのでもう一度ヒントを読みました。 次のようなヒントに注目しました。 go help build のフラグ一覧を眺め、一時ディレクトリに言及しているフラグを探してみましょう。見つけたフラグの説明文を読み、それが「デフォルトでは行われないことを追加で行う」フラグなのか、「デフォルトの動作を止める」フラグなのかを見分けてみましょう。 そこで、再び pkg.go.dev/cmd/go でフラグ一覧を調べました。 すると -work というフラグがあり、「一時作業ディレクトリの名前を表示し、終了時にそれを削除しない」と説明されていました。 この一時作業ディレクトリが、先ほどから調べていた $WORK ディレクトリです。 つまり、 -work を付けないと $WORK は実行後に削除されます。 そこで -work を付けて実行しました。 go run -a -work main.go 今度は $WORK ディレクトリに移動でき、中に実行ファイルがありました。 ここで時間がなくなり、答え合わせの時間になりました。 答え合わせの中で、 -a とキャッシュの関係を理解しました。 次の 2 つのコマンドを実行して比べます。 go run -a -work main.go go run -work main.go -a ありでは $WORK の中に中間ファイルと実行ファイルがありましたが、 -a なしでは $WORK の中は空でした。 答えの中で参照されていた Go 1.24 のリリースノート を読みました。 次のように書かれています。 Executables created by go run and the new behavior of go tool are now cached in the Go build cache. This makes repeated executions faster at the expense of making the cache larger. See #69290. つまり、Go 1.24 から go run でビルドした実行ファイルもビルドキャッシュに保存されるようになった、ということです。 -a を付けると $WORK の中でビルドが実行され、できた実行ファイルがキャッシュに残ります。 -a を付けない場合、ソースに変更がなければビルドを省略してキャッシュ済みの実行ファイルをそのまま実行するため、 $WORK は作られるものの中身は空になります。 以上から、設問2の答えは次の 3 点です。 何もフラグを付けない場合、 $WORK ディレクトリは一時的に作成され、実行が終わると削除される $WORK の中にあった実行ファイルは、ビルドキャッシュのディレクトリに保存される -work を付けると、 $WORK ディレクトリが削除されずに残る ワークショップで得たこと 今回のワークショップでは、 go help と pkg.go.dev を頼りに公式ドキュメントを読み進めることができました。 公式ドキュメントの読み進め方という点では、次のことを意識しました。 go help コマンドを初めて触り、その中身を理解するというステップを踏んだことで、公式ドキュメントを読むことへのハードルが少し下がりました。 公式ドキュメントは翻訳して読んでよいと知ったことでもハードルが下がり、調べやすくなりました。 そのうえで、ページ内検索で公式ドキュメントを検索しながら地道に読んでいくことを意識して取り組みました。 今回のテーマがコマンドツールだったので、コマンドツールの調べ方として意識したこともあります。 go run を実際に動かして観察し、フォルダやファイルが存在するかを確かめたり、フラグを付けて挙動がどう変わるかを見たりしました。 加えて、普段使っているコマンドツールはどのように動いているのだろうと自分なりの仮定を持ってみると、疑問が浮かび、より良い調査ができると感じました。 一次情報を押さえながら進めたので、理解が積み上がっていく感覚がありました。 一次情報にあたる経験に加えて、 go run の仕組みへの理解も深まり、他のコマンドも同じやり方で調べてみたくなりました。 今後 Go を学ぶときにも、この調べ方を使っていきたいです! Go × SIMDで高速化するベクトル検索 ~ ルーフラインモデルでSIMDが効く境界を探れ! 講師: Hiromu Nakamura さん レポート: 黒髙 こんにちは、開発本部の 黒髙 です。普段は デリッシュキッチン の開発に携わっています。 私は、 Hiromu Nakamura さんによるワークショップ「 Go × SIMDで高速化するベクトル検索 ~ ルーフラインモデルでSIMDが効く境界を探れ! ~ 」に参加しました。 このワークショップでは、GoでSIMDを使う方法に加えて、計測結果からボトルネックを見極め、次の高速化手法を選ぶ進め方を学びます。教材本編は、次の流れで構成されています。 ベクトル検索とSIMDの仕組み、Goでの使い方を知る 「ルーフラインモデル」で計算能力とメモリ帯域から性能の上限を考え、マシンの上限を測る スカラ版の全探索を基準として測る(Stage 0) 内積の計算をSIMDで高速化する(Stage 1) int8量子化でデータ量を減らす(Stage 2) 1bit量子化でさらにデータ量を減らし、速度と検索精度の変化を見る(Stage 3) 絞り込んだ候補を元のfloat32で再採点し、検索精度を回復する(Stage 4) 私はStage 2まで取り組みました。ここでは、SIMDの機能と、実際に確認できた高速化の効果を中心に紹介します。 資料と教材は以下で公開されています。 speakerdeck.com github.com 題材は、384次元のベクトル10万件から、クエリとの内積が大きい上位10件を探す処理です。ベクトル検索では、文章などを数値の並びで表し、その近さを使って検索します。 SIMDとは SIMD (Single Instruction, Multiple Data)は、1つの命令で複数のデータに同じ演算を適用するCPUの機能です。その働きを、今回のワークショップで扱う内積計算を例に見てみます。 内積は、2つのベクトルの同じ位置にある要素を掛け合わせ、その結果をすべて足す計算です。8要素のベクトルなら、次のようになります。 a = [1, 2, 3, 4, 5, 6, 7, 8] b = [2, 3, 4, 5, 6, 7, 8, 9] 内積 = 1×2 + 2×3 + 3×4 + 4×5 + 5×6 + 6×7 + 7×8 + 8×9 = 2 + 6 + 12 + 20 + 30 + 42 + 56 + 72 = 240 Goで素直に書くと、次のようになります。 var sum float32 for i := range a { sum += a[i] * b[i] } このループでは、 a[i] と b[i] を1組ずつ掛け、その結果を1つの変数 sum に足していきます。8要素なら、この処理を8回繰り返します。このように、演算で値を1要素ずつ扱うのが スカラ処理 です。 一方、8要素を扱えるSIMD命令なら、 1×2 から 8×9 までの掛け算をまとめて実行できます。掛け算の部分に注目すると、スカラ命令では8回かかるところを、SIMD命令なら1回で処理できます。掛け算命令の実行回数は1/8です。 SIMDで8組の掛け算を1命令で実行し、結果を合計して内積を求める模式図 図1:SIMDで8組の掛け算をまとめて実行し、その結果を合計して内積を求めます。 どちらも8組の掛け算を行いますが、SIMDではそれを1つの命令にまとめられます。SIMDでまとめて掛けた結果は [2, 6, 12, 20, 30, 42, 56, 72] という8個の値なので、内積を得るには最後にこれらを合計する処理が必要です。 このように、同じ演算を大量の要素に繰り返す処理で、1命令あたりに処理できる要素を増やせることがSIMDの便利な点です。今回の検索では、384要素の内積を10万件のベクトルに対して繰り返すため、SIMDによる高速化が期待できます。SIMDは1つのCPUコアの中でも利用できる仕組みです。 GoからSIMDを使う Go 1.27では、実験的なパッケージ simd/archsimd を使い、Goの型やメソッドでCPU固有のSIMD演算を扱えます。 archsimd 自体はGo 1.26で導入され、1.27ではAPIの改訂やarm64・WebAssemblyへの対応が追加されています。まだAPIは安定しておらず、ビルド時に GOEXPERIMENT=simd を指定して有効化します( Go 1.27リリースノート )。 CPUには、計算中の値を置く レジスタ という小さな記憶領域があります。今回のamd64向け実装では、256bit幅のSIMDレジスタを利用します。 float32 は1個32bitなので、1つのレジスタに8個の値が入ります。この1要素ぶんの区画を レーン と呼びます。 Goでは、この「32bitの値を8レーン」という形を archsimd.Float32x8 という型で表します。先ほどの図と同じく、8要素をまとめて扱えます。次のコードは、384要素ある a と b のうち、先頭8要素を処理する部分を示したものです。 var acc archsimd.Float32x8 // 8レーンとも初期値は0 va := archsimd.LoadFloat32x8(a) // aの先頭8要素を読む vb := archsimd.LoadFloat32x8(b) // bの先頭8要素を読む acc = va.MulAdd(vb, acc) // 各レーンでva×vbをaccへ足す LoadFloat32x8 は、スライスから8要素を読み込む関数です。 va と vb にはそれぞれ8個の値が入り、 acc にも途中結果をためる場所が8個あります。 va.MulAdd(vb, acc) では、各レーンで「 va の値 × vb の値 + acc の値」を計算します。 MulAdd は、掛け算と足し算をまとめて行うFMA(Fused Multiply-Add)に対応します。 Float32x8 では、この積和演算を8レーンまとめて1つの命令で行います( MulAddのドキュメント )。 a と b の読み込む位置を進めながら同じ処理を繰り返すと、各レーンに積和の途中結果をためていけます。最後にレーンごとの値を合計すると、内積が求まります。 このようなSIMD命令を、アセンブリやcgoを自分で書かずに、Goの型やメソッドを通して利用できるのが archsimd の特徴です。 ベンチマークで効果を確認する ここからは、冒頭で紹介したStage 0(スカラ版の計測)→Stage 1(SIMD化)の流れに沿って、実際の効果を見ていきます。まず make bench0 でスカラ版の全探索の速度を測り、続く make bench1 でスカラ版とSIMD版を比較しました。 計測には、ワークショップで用意された教材のGitHub Codespaces環境を使いました。実行環境はLinux / amd64で、CPUはAMD EPYC 7763でした。 教材には、内積単体を測るベンチマークと、10万件すべてとの内積計算から上位10件の選択までを含む、検索全体のベンチマークがあります。SIMD版も全件を走査する流れは同じで、内積の計算をSIMDに置き換えています。実装では途中結果をためる変数を acc0 と acc1 の2本に分け、互いの結果を待たずに計算できるようにしています( 教材の内積の実装 )。 8要素をまとめて計算できても、処理全体がそのまま8倍速くなるとは限りません。以下は、 make bench1 で内積単体と検索全体を計測した結果です。 計測対象 スカラ版 SIMD版 高速化の倍率 float32の内積 393.8 ns 58.71 ns 約6.7倍 10万件の検索 36.10 ms 9.76 ms 約3.7倍 内積単体では約6.7倍、検索全体でも約3.7倍の高速化を確認できました。 内積単体の改善が、そのまま検索全体の倍率になるわけではないことが分かります。検索ではベクトルの読み込みも必要で、計算だけを速めても読み込みが追いつかなければ、CPUはデータを待つことになります。こうした性能の上限を考えるために、スライドではルーフラインモデルが紹介されていました。 Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~ - Speaker Deck この図は、横軸が算術強度、縦軸が1秒あたりの演算回数で、屋根の形をした線が性能の上限を表しています。 算術強度は「演算回数/バイト」、メモリ帯域は「バイト/秒」なので、両者を掛けると「演算回数/秒」になります。これが、メモリからのデータ供給によって決まる性能の上限です。 線が折れ曲がる点(リッジ)より左側では、算術強度 × メモリ帯域 < 演算ピークとなります。CPUの計算能力より、データを供給する速さが低い上限を作るため、この領域の上限はメモリ帯域によって決まります。算術強度を上げると、同じ転送量でできる計算が増えて上限も上がるため、グラフは右上がりの斜線になります。 リッジより右側では、算術強度 × メモリ帯域 > 演算ピークとなるため、CPUの計算能力が性能の上限を決めます。算術強度をさらに上げてもこの上限は変わらないので、グラフは水平になります。実際の計測点がこの線より下にある場合は、SIMDなどで計算を効率化し、上限に近づけられる可能性があります。 int8量子化でデータ量を減らす メモリから読み込めるデータ量には1秒あたりの上限があるため、同じ件数のベクトルでもデータ量が少なければ読み込みにかかる時間を短くできます。この読み込み時間を減らして検索を速めるのが、Stage 2(int8量子化)です。 この段階では、 make bench-int8 でint8量子化を使った実装を計測しました。量子化は、値を少ないビット数で近似して表す方法です。float32をint8に変換すると、走査するベクトル本体は153.6 MBから38.4 MBになります。 検索全体の時間は、Stage 1のfloat32 SIMD版の約9.76 msから、int8 SIMD版の約4.00 msへ短縮され、さらに約2.4倍速くなりました。量子化によるデータ量の削減と、int8向けのSIMD計算を組み合わせた効果です。 int8の内積単体でも、スカラ版の412.8 nsからSIMD版の32.17 nsへ、約12.8倍の高速化を確認できました。 ただし、量子化は値そのものを変えるので、全探索をしても、検索結果が正解とずれる可能性があります。そのため、教材ではRecall@10(正解の上位10件と何件一致したか)という指標を用いて、検索結果の精度も検証していました。この評価では、元のfloat32版で得られた上位10件を正解としています。 ワークショップを体験して 今回のワークショップでは、Goの実験的なSIMDパッケージを使い、ベクトル検索を段階的に高速化する方法を学びました。ルーフラインモデルで計算能力とメモリ帯域の制約を考えながら、SIMDによる内積の高速化から、量子化によるデータ量の削減へと進む流れでした。資料では、さらに1bit量子化と再採点を組み合わせて、速度と検索精度の両立を目指すところまで紹介されていました。 Goのコードを動かして内積や検索が速くなる様子を確かめ、SIMDによる並列化の恩恵を感じることができました。さらに、量子化でデータ量を減らすといった高速化の手法にも、手を動かしながら触れられてよかったです。 まとめ Go Conference運営の皆さん、今年もカンファレンスを開催していただきありがとうございました! 昨年との違いとして気づいたのは、今回はGo Conferenceだけでなく「DroidKaigiで弊社を見かけた」、「iOSDCにも参加予定」といったエンジニアの方が多数みられたことです。 DroidKaigi のアンケートでもある通り、どの企業様のエンジニアも越境する意識があるのだなと感じさせられました。 今年もたくさんのGopherとお話したり、セッションを拝聴したりと充実した1日を送ることができました! Go Conference 2027もぜひ参加したいです! 非公式アフターイベント Go BASH Vol.3 のお知らせ ANDPAD、OPTiM、Resilire、エブリーの4社合同で、非公式アフターイベント Go BASH Vol.3 を開催します! 2026年9月30日(水) 19:30〜、会場はエブリー本社です。Go Conference 2026 の感想戦や各社のセッションを用意していますので、ぜひご参加ください! connpass.com 最後に エブリーでは、ともに働く仲間を募集しています。 テックブログを読んで少しでもエブリーに興味を持っていただけた方は、ぜひ一度カジュアル面談にお越しください! corp.every.tv 最後までお読みいただき、ありがとうございました!




















