
「C++Builder 12.3で安全性を確保: サニタイザーの導入」に関するブログでは、新しいC++モダンツールチェーンは、「未来を支える基盤」として紹介してきました。
そのブログの中では、
「これがあれば、今までできなかったことができる」「ユーザーに真の価値を届けられる」と。そして今、それが実現されつつあります。
とお伝えいたしました。
C++Builder 12.2では、CMake対応と、驚くべきコンパイラ性能を実現しました。(ちなみにC++Builder 12.3では、さらに最大20%向上しています)
C++Builder 12.3は、品質向上が主な目的ですが、新しいツールチェーンによって、これまで実現できなかったいくつかの新機能も追加されています。中でも注目すべきは、サニタイザのサポートと、新しいCPU命令セットによるパフォーマンスの向上で、C++Builderのユーザーへ特にお知らせしたいポイントです。
Table of Contents
CPU命令セット
CPUは世代を重ねるごとに、新しい命令や機能を備えていきます。多くの場合、それは処理速度の向上につながります。最近のアプリでは、より効率的なチップの上で動作するだけでなく、「ベクトル化」と呼ばれる手法で処理を高速化するのが鍵となっています。
ベクトル化とは、一度に複数のデータを処理することです。例えば、文字列内で特定の文字を探す場合、通常は1文字ずつ処理しますが、ベクトル化されると4文字や8文字をまとめて処理できるようになります。これにより、処理速度が大幅に向上します。
(ベクトル化は「並列処理」の一種ですが、一般的な「スレッドによる並列処理」とは違います。1つのスレッドが一度に多くのデータを扱うという意味で、複数スレッドで同時に処理するのとは区別して考える必要があります。ただし、スレッド数が多いほど、各スレッドがベクトル化の恩恵を受けやすくなります!)
補足: 自動ベクトル化とは、コンパイラがソースコードを解析し、SIMD命令(1つの命令で複数データを処理)に自動変換する最適化手法です。これにより、ループ処理や配列操作などのコードが高速化されます。ただし、ベクトル化の対象となるにはいくつかの条件(依存関係がない、メモリアクセスが予測可能など)を満たす必要があり、すべてのコードが自動でベクトル化されるわけではありません。コンパイラの種類や最適化レベルによって、ベクトル化の可否や効果に差が出る点に注意が必要です。参考: https://en.wikipedia.org/wiki/Automatic_vectorization
これまで、浮動小数点演算や整数演算、ビット操作などに対応するさまざまな命令セットが登場してきました。
それでも、長年にわたってエンバカデロではSSE2という基本命令セットにとどまっていました。これは、Windowsの64-bit アプリにおいて基盤となる命令セットです。その後、多くの進化がありました。そして、エンバカデロは最新のハードウェア上でアプリをより高速に動作させる機会を皆さんに提供したいと考えています。C++Builder 12.3であれば、それが可能になります。
C++Builder 12.3の新機能
C++Builder 12.3では、以下の6つの命令セットに新たに対応しました。
- SSE3
- SSSE3(これは誤字ではありません)
- SSE 4.1 / 4.2
- AVX
- AVX2

これらは、現代のアプリで広く使われている命令セットです。特にAVX2は登場から少し時間が経っていますが、ここ数年で多くのCPUに標準搭載されるようになりました。
これらの命令セットを利用するには、「プロジェクトオプション」→「ビルド」→「C++コンパイラ」→「命令セット(COFFのみ)」から選択します。
ここでの「COFF」とは、新しいbcc64xコンパイラを指します。一つ選択すれば、それより前の命令セットも自動的に有効になります。
ただし、注意が必要です。利用者のPCがその命令セットに対応している必要があります。命令セットが登場した年ではなく、「それが標準化された時期」を確認する必要があります。例えば、命令セットは初めて登場した時点では一部のハイエンドCPUにしか搭載されていないことが多いため、実際のアプリケーション開発では、ユーザーの多くが対応している環境(=標準的なPC)で問題なく動くかがとても重要ということです。例えば、大まかにIntel CPUの例で表すと以下のようになります。
命令セット | 登場時期(初搭載) | 標準化されたとみなせる時期(普及) |
---|---|---|
SSE3 | 2004年(Pentium 4) | 2006〜2007年頃(Core 2普及) |
SSSE3 | 2006年(Core 2) | 2008〜2009年頃 |
SSE4.1 / 4.2 | 2007〜2008年(Penryn / Nehalem) | 2010年頃〜(Nehalem世代普及後) |
AVX | 2011年(Sandy Bridge) | 2013〜2014年頃(Haswell普及) |
AVX2 | 2013年(Haswell) | 2016年頃〜(Skylake以降が主流) |
ベクトル化処理
新しいClangベースのモダンコンパイラは、ソースコードから自動的にベクトル化可能な箇所を検出し、SIMD命令を生成することができます。最適化レベルを上げることでその精度や適用範囲が広がりますが、さらにベクトル化を促すヒントとして __restrict__ キーワードを使用することもできます。
補足: __restrict__ は、「このポインタ同士は別のデータを指している」とコンパイラに伝えるためのキーワードです。これによって、処理の重なりを気にせずに高速化(最適化)しやすくなります。ただし、Clangコンパイラはとても慎重なので、__restrict__ をつけても常に速くなるとは限りません。
最適化されるかどうかは、コードの書き方やデータの使い方にもよるため、実際にプログラムを動かして効果を確かめる(ベンチマークを取る)ことが大切です。
詳しくは、以下のドキュメントをご参考ください。
また扱っているデータの種類に応じて、最適な命令が使われます。特にC++のSTLアルゴリズムなどは、非常に効率よくベクトル化される傾向があります。
パフォーマンスの大幅向上!
今回のアップデートは、たった1回のリリースで、CPU技術の約15年分を一気に取り込んだと言えるほどの進化です!これは、新しいコンパイラの力を実感できる良い例です。そして、現在広く使われている最新のCPUにも対応しています。
新しい命令セット対応と自動ベクトル化機能により、パフォーマンス向上が期待できる最適化が設定ひとつで利用可能になります。特に、高速化が求められる数値計算やデータ処理系のアプリにおいて、開発工数を増やさずに恩恵を受けられるのは大きな魅力です。
ここから先は、新しいツールチェーンと共に、さらに未来へ進んでいけるでしょう。
今回のアップデートが、皆さんの開発に役立ち、より速く、効率的で、高性能なアプリをユーザーに届けられるようになることを願っています。