いくつかの文字列があり、その文字列内の文字 ! の出現回数を数えたいとします。古いタイプのプログラマなら、C++では次のように問題を解決するでしょう。

size_t c = 0;
for (const auto &str : strings) {
    c += std::count(str.begin(), str.end(), '!');
}

範囲を使ってより洗練された方法を取ることもできます。

for (const auto &str : strings) {
    c += std::ranges::count(str, '!');
}

などです。

しかし、より高速にしたい場合はどうでしょうか?この関数をアセンブリに書き換えたいと思うかもしれません。私はそうすることにし、GrokとClaudeの両方をAIとして使い、友好的な競争を設定して楽しみました。

私の関数から始め、その後、AIにアセンブリで最適化するよう依頼しました。重要なのは、AIが私の使用しているマシンを知っていたため、ARMアセンブリで書き始めることができた点です。

繰り返しのプロンプトによって、次の関数を得ました。

  • count_classic: 参照用にC++標準ライブラリの std::count を使用。
  • count_assembly: 基本的なARM64アセンブリループ(バイト単位の比較)。Grokによって書かれた。
  • count_assembly_claude: NEON命令を使用したClaudeのSIMD最適化版(16バイトチャンク)。
  • count_assembly_grok: Grokの最適化版(32バイトチャンク)。
  • count_assembly_claude_2: Claudeのさらに最適化された版(複数のアキュムレータを使用した64バイトチャンク)。
  • count_assembly_grok_2: Grokの最新版(改善されたアキュムレータ処理による64バイトチャンク)。
  • count_assembly_claude_3: 追加の最適化を施したClaudeの最も高度な版。

ご理解いただけるでしょう。

では、パフォーマンスはどうでしょうか?最大1キロバイトのランダムな文字列を使用します。すべてのケースで、関数が正しいカウントを提供することをテストします。コードを詳しく調べていないため、コード内にミスが隠れている可能性があります。

文字列あたりの平均命令数を記録します。

name instructions/string
classic C++ 1200
claude assembly 250
grok assembly 204
claude assembly 2 183
grok assembly 2 176
claude assembly 3 154

繰り返しの最適化により、命令数を8分の1に削減しました。実行時間も同様に短縮されます。

AIに最適な選択肢をCで書き直させることができるでしょうか?はい、SIMD組み込み関数を使用すれば可能です。したがって、このケースではコードをアセンブリに残しておく利点はありません。

未解決の問題として、AIがCやC++のような高水準言語を使用する場合に不可能な最適化を見つけられるかどうかという点があります。これは興味深い問題であり、後日答えるつもりです。現時点では、AIは私のC++コンパイラを上回ることができます!

ソースコードはこちらで入手できます

Published by

Post navigation