Intel Architecture プログラミング

提供:yonewiki
2022年9月26日 (月) 11:51時点におけるYo-net (トーク | 投稿記録)による版 (ページの作成:「言語と開発環境へ戻る。   == '''概要''' ==  インテルアーキテクチャーはWindows OSの命令を処理するCPU インテルプロッセッサの技術で、Visual C++コンパイラやGCCコンパイラでこのアーキテクチャーを使うことができるようになっています。この命令セットはいわば、最先端アセンブラ言語と言える高度なアセンブラの…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

言語と開発環境へ戻る。

 

概要

 インテルアーキテクチャーはWindows OSの命令を処理するCPU インテルプロッセッサの技術で、Visual C++コンパイラやGCCコンパイラでこのアーキテクチャーを使うことができるようになっています。この命令セットはいわば、最先端アセンブラ言語と言える高度なアセンブラの命令を理解することにもつながります。プロセッサあるところにアセンブラあり、IntelのCPUにもアセンブラがある。SIMDと呼ばれるSingle Instructure Multiple Dataという方式のCPU処理方式で、一つの命令で複数のデータを処理できるという方式です。


 え?そんな低レベルのプログラミングって今どき必要なの?ってあると思いますが、無駄がなく、高速に計算をするときは、このレベルにまで落とし込んだプログラミングにすることは、よくあって、画像処理や動画処理の根幹をなしています。こんな難しい技術を覚えても、さほど役に立たないかもしれません。Intelの英語WebSiteとかにいくと命令セットの仕様が公開されています。最近はVisual C++でちょちょいっとやるだけで使えるようになっているので、知っててもいいんじゃない?という基本的なアセンブラ処理もあるので、面白半分で使ってみるのもいいかもしれません。いつか役に立つときはあると思う。


 SIMDってのはフリンの分類というコンピュータアーキテクチャー(情報処理の構造)のひとつで、他にもMIMD(Multiple Instruct Multiple Data)というマルチコア、マルチプロセッサのような方式、SISD(Single Instruct Single Data)という最も単純な方法、MISD(Multiple Instruct Single Data)という高度な信頼性をひつようとする方式、発展的にはSPMD(Single Program Multiple Data)、やSPSD(Single Program Single Data)というスーパーコンピュータ(その時代時代の最先端のコンピュータ)のようなものが扱う方式もあります。さらにはSIMT(Single Instruct Multiple Thread)やMIMT(Multiple Instruct Multiple Thread)、SPMT(Single Program Multiple Thread)やMPMT(Multiple Program Multiple Thread)といったものもあります。組み合わせが全部あるだけですね。Programとつくのは一命令がプログラムのようにふくざつなものを一度に処理するもので、ThreadってなってるのはDataがオブジェクトと呼ばれるくらい大きいものになっていてThreadとして、扱われるくらいのDataになるって感じですね。

プログラムの例

 Win32コンソールアプリケーションをつくります。そして以下のようなプログラムをMain関数にするとMOVDQAというデータ転送命令を使うことができます。

#include "stdafx.h"


int main(int argc, char *argv[])
{
	__declspec(align(16)) unsigned int src[4] = { 1, 256, 1024, 65536 };
	__declspec(align(16)) unsigned int dst[4];

	__asm
	{
		movdqa	xmm0, src
		movdqa  dst, xmm0
	}

	printf(" source:%7d,%7d,%7d,%7d\n", src[0], src[1], src[2], src[3]);
	printf(" result:%7d,%7d,%7d,%7d\n", dst[0], dst[1], dst[2], dst[3]);

	return 0;
}


■実行結果

 source:      1,    256,   1024,  65536
 result:      1,    256,   1024,  65536

 11行目からmovdqaが使われています。第一オペランドのxmm0レジスタに第二オペランドのint配列srcからまとめて格納転送されます。後ろのオペランドから、前のオペランドにデータが転送されている感じです。C++言語側で確保した配列との連携をする場合この操作で、間違いが起こらないようにするには配列が連続していることが重要になりますので、__declspec(align(16))という宣言をしました。16としたところには2の階乗になっていれば、その分だけ連続して配置するように働きます。アライメントといいます。タイヤのアライメントしか知らない人や半導体プロセスのLithography工程や重ね合わせ検査工程やその他、特定位置を検査する装置で必要な画像認識処理のアライメントとかしか知らない人もいるかもしれませんが、位置出しという日本語がちょうどいい感じのニュアンスに変換できると思います。


 12行目ではxmm0レジスタから配列へデータが転送されて、srcの内容がdstにコピーされるという動きになっています。


 このように、C++言語での操作の中に制限付きの配列変数を使ったり、Intel Architectureの低レベル命令を駆使することで、ものすごく特殊なデータの転送処理が一括で処理することができます。通常のプログラミングだけではなし得ない、高速な手法です。


 ちなみにmovdqdという命令を使うにはIntel Pentium4プロセッサから導入されたIntel SSE2テクノロジという命令セットがCPUに搭載されていなければ、このプログラムをコンパイルすることも、実行することもできません。ほとんどの後継のプロッセッサにはこれらの各種テクノロジは互換性をもって搭載されていますので、それらのプロセッサでも動作します。管理人のCore i7 第3世代やAtom x5 Z-8300プロセッサでも動作しました。Core i7は2012年のモデルのPCです。2018年は第9世代を迎えようとしています。進化が凄い。今でも十分速い動作してますので、買い替えたいとは思わないです。おどろくほど、快適なんでしょうけど。3Dのレンダリングとか動画の変換とか、そういう作業をあんまりしないので、恩恵はあまりないですね。それよか人間が動く方が遅くて、入力待ちの方が多いっす。生活の全てを自動化したいっす。お金持ちの人は、バシバシとPCを新調していただいて、無駄に速いPCを使って頂ければと思います。妬み。どうせ使いこなせてない人がほとんどなんでしょう。妬み。嫉み。(ねたみ。そねみ。)話が脱線しました。


 こういった命令セットを説明していくと広辞苑くらいの情報量が必要になってきます。現にIntelのアーキテクチャー説明資料もPDFで何千ページというボリュームになっています。よく使いそうなものを、ここでは紹介していくかもしれません。それでも、きっと書き終わったころには定年を向かていることでしょう。

  言語と開発環境へ戻る。