別件シリーズでアセンブラ書いたりしてます。今回はGemini様にアセンブラを書いてもらおうと試みました。「A64のアセンブラで長さ16のfloat型ベクトルの内積を求めるプログラムを作って」とプロンプトに入力。「作って」は下さるのですが、Pythonのプログラムをお願いした時のような、切れがないです(個人の感想です。)
※Google様の生成AI、Gemini(無料プランだけれども)を使ってソフトをコーディングしてもらっています。
※実機動作確認には以下を使用しております。
-
- Raspberry Pi 4 model B、Cortex-A72コア(ARMv8-A)
- Raspberry Pi OS (64bit) bullseye
- gcc (Debian 10.2.1-6) 10.2.1 20210110
Gemini様のご回答3案
茫漠とした年寄の問いかけに対して、Gemini様はいつものように3案返してくれました。こんな感じ。
案1)アセンブラのコードではある。もっともらしいけれど、?なところもあるソースが生成された。結果を出力するところまでは面倒みてくれていない。
案2)アセンブラのコードではなく、C言語コードが生成された。しかし先頭で、
#include <arm_neon.h>
と「ネオン使うぞ」とアピールしている。コンパイラが頑張ってくれればSIMD使ったオブジェクトコードが生成されるハズ。コンパイラに丸投げ?
案3)アセンブラのコードではある。案1と大差なし。
ということで、実際のA64機上でプログラムを動かしてみました。
まずはコンパイラ任せの案2から
案2はコンパイラまかせではありますが、生成しているのがCのコードなので「それなり」の品質です。しかし、Gemini様生成のコードをほぼそのまま gcc に食わせたところ以下のエラーが出ました。
うっかりものだな~。printfしているのに stdio.h をインクルードするの忘れているじゃん。人の(Geminiの)ことは言えないか。1行補ってやればビルドはOK。
ここで大事なのは gcc にオプション -O0 など渡すとSIMD命令を生成してくれないことです。スカラーの浮動小数点命令が生成されてました。しかし -O3 と最適化をお願いすれば、ほれこのように(以下は生成されたアセンブラのソース)
下の方に v0.4s とかSIMDレジスタが並んでいるのが見えますな。SIMD化されておりますで。その計算結果が以下に。
長さ16のベクトルの片方には1.0から16.0までの数字(1.0キザミ)が、もう一方には2.0から17.0までの数字(1.0キザミ)が入っているので上記の1632.0は期待通りの結果です。
案2はSIMD命令を使ったオブジェクトコードは得られたけれどもアセンブラじゃない(正確に言えばアセンブラにするところはコンパイラにお任せ)だと。
案1のアセンブラ
案1のアセンブラソースは結果を出力する部分が不在のmainルーチンだったので、計算部分はGemini様のコードそのままで、Cのmainを一皮かぶせて結果出力がだせるようにしてみました。コンパイルしたところが以下です。
アセンブラ部分でエラー出まくり。Gemini様のソースをファイルにコピーするところから「いいんかな?」と思っていたのですが、やっぱり。。。
結局手修正してしまいました。Gemini様のオリジナルソースはSIMD命令使ってないだけでなく、スカラーの積和命令も使ってないプレイン・バニラ味だったので、とりあえずスカラーの積和算 fmadd を使ってしまいました。こんな感じ。
でもこれでは自分で書いたのと変わらんな。。。Gemini様、アセンブラは苦手なのかも?