コグノスケ


link 未来から過去へ表示  link 過去から未来へ表示(*)

link もっと前
2020年7月8日 >>> 2020年7月17日
link もっと後

2020年7月8日

GCCを調べる - その15-3 - ベクトルレジスタを使用するmachine mode

目次: GCC

前回(2020年7月7日の日記参照)はベクトルレジスタが選択されてしまう仕組みが何となくわかりました。

今回やりたかったことを復習しておくと「ベクトルの演算以外でベクトルレジスタを使わないでほしい」でした。つまりira_prohibited_class_mode_regs[cl][j] のうちベクトル以外のmachine modeかつベクトルレジスタに相当するビットを「セット」つまり割り当て禁止状態にすれば良いはずです。

配列の次元のうちclはレジスタのクラス(enum reg_class)で、jはmachine modeです。レジスタのクラスは以前(2020年3月28日の日記参照)ちょっとだけ使いました。幸いなことに、今回はレジスタのクラスは気にしなくて良いです、というかコードのif文の条件hard_regno_mode_ok(hard_regno, (machine_mode) j) を見るとわかるように、そもそもレジスタのクラスが渡されないので、ターゲット側(=RISC-V依存の実装部分)で何もできないです。

重要なのはmachine modeで、ベクトル以外のモード(浮動小数点など)だったらベクトルレジスタを割り当て禁止状態にすれば良いです。

targetm.hard_regno_mode_ok() のRISC-V向け実装

// gcc/config/riscv/riscv.c

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  unsigned int nregs = riscv_hard_regno_nregs (regno, mode);

  if (GP_REG_P (regno))
    {
      if (!GP_REG_P (regno + nregs - 1))
	return false;
    }
  else if (FP_REG_P (regno))
    {
      if (!FP_REG_P (regno + nregs - 1))
	return false;

      if (GET_MODE_CLASS (mode) != MODE_FLOAT
	  && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
	return false;

      /* Only use callee-saved registers if a potential callee is guaranteed
	 to spill the requisite width.  */
      if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
	  || (!call_used_or_fixed_reg_p (regno)
	      && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
	return false;
    }
  else if (VP_REG_P (regno))    //★★前回足した実装
    {
      return true;
    }
  else
    return false;

...

ここでベクトル系のmachine modeを直接記述(mode == V64SImodeなど)しても間違いではないと思うのですが、単純にモードがたくさんあると鬱陶しいですし、該当するモードがあとで増えたときの修正が大変です。こういうときはmachine modeのクラスが便利です。クラスってなんだったかというと、machmode.defやriscv-modes.defに書いたあれです。

machine modeクラスの定義

// gcc/machmode.def

...

/* Basic integer modes.  We go up to TI in generic code (128 bits).
   TImode is needed here because the some front ends now genericly
   support __int128.  If the front ends decide to generically support
   larger types, then corresponding modes must be added here.  The
   name OI is reserved for a 256-bit type (needed by some back ends).
    */

//★★MODE_INTクラスになる

INT_MODE (QI, 1);
INT_MODE (HI, 2);
INT_MODE (SI, 4);
INT_MODE (DI, 8);
INT_MODE (TI, 16);

...


// gcc/config/riscv/riscv-modes.def

//★★MODE_FLOATクラスになる

FLOAT_MODE (TF, 16, ieee_quad_format);

//★★以前、追加した実装
//★★VECTOR_MODEの場合は少し特殊で、MODE_VECTOR + 最初の引数 クラスになる
//★★この例だとMODE_VECTOR_INTになる

VECTOR_MODE (INT, SI, 32);
VECTOR_MODE (INT, SI, 64);

クラスは上記の通り各所の *.defにて定義されますが、正直言ってどこにあるかわかりにくいし、クラスの名前も見えません。machine modeとクラスの対応を確認するだけなら、ビルド時に生成されるinsn-modes.cを見たほうが早いです。

machine modeとクラスの対応、早見方法

// build_gcc/insn-modes.c

const unsigned char mode_class[NUM_MACHINE_MODES] =
{
  MODE_RANDOM,             /* VOID */
  MODE_RANDOM,             /* BLK */
  MODE_CC,                 /* CC */
  MODE_INT,                /* BI */
  MODE_INT,                /* QI */
  MODE_INT,                /* HI */
  MODE_INT,                /* SI */
  MODE_INT,                /* DI */
  MODE_INT,                /* TI */
  MODE_FRACT,              /* QQ */
  MODE_FRACT,              /* HQ */
  MODE_FRACT,              /* SQ */
  MODE_FRACT,              /* DQ */
  MODE_FRACT,              /* TQ */
  MODE_UFRACT,             /* UQQ */
  MODE_UFRACT,             /* UHQ */
  MODE_UFRACT,             /* USQ */
  MODE_UFRACT,             /* UDQ */
  MODE_UFRACT,             /* UTQ */
  MODE_ACCUM,              /* HA */
  MODE_ACCUM,              /* SA */
  MODE_ACCUM,              /* DA */
  MODE_ACCUM,              /* TA */
  MODE_UACCUM,             /* UHA */
  MODE_UACCUM,             /* USA */
  MODE_UACCUM,             /* UDA */
  MODE_UACCUM,             /* UTA */
  MODE_FLOAT,              /* SF */
  MODE_FLOAT,              /* DF */
  MODE_FLOAT,              /* TF */

...

  MODE_COMPLEX_FLOAT,      /* SC */
  MODE_COMPLEX_FLOAT,      /* DC */
  MODE_COMPLEX_FLOAT,      /* TC */
  MODE_VECTOR_INT,         /* V32SI */
  MODE_VECTOR_INT,         /* V64SI */
};

ベクトル系のmachine modeを引っ掛けるにはMODE_VECTOR_INTを使えば良さそうです。今の実装では使っていませんがRISC-Vのベクトルは浮動小数点のベクトル(MODE_VECTOR_FLOAT)も扱えるはずなので、これも条件に追加しておきましょう。

targetm.hard_regno_mode_ok() のRISC-V向け実装、修正版

// gcc/config/riscv/riscv.c

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  unsigned int nregs = riscv_hard_regno_nregs (regno, mode);

  if (GP_REG_P (regno))
    {
      if (!GP_REG_P (regno + nregs - 1))
	return false;
    }
  else if (FP_REG_P (regno))
    {
      if (!FP_REG_P (regno + nregs - 1))
	return false;

      if (GET_MODE_CLASS (mode) != MODE_FLOAT
	  && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
	return false;

      /* Only use callee-saved registers if a potential callee is guaranteed
	 to spill the requisite width.  */
      if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
	  || (!call_used_or_fixed_reg_p (regno)
	      && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
	return false;
    }
  else if (VP_REG_P (regno))    //★★前回足した実装
    {
      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT
	  && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)    //★★今回足した実装
	return false;

      return true;
    }
  else
    return false;

...

修正後のコンパイラは浮動小数点数を60個使うコードを正常にコンパイルできます。たったこの3行を説明するだけで、えらい時間を費やしました。GCCは魔界ですね。

お気づきの方もいるかと思いますが、実は1つ上のelse if節にほぼ全く同じ判定文が既にあります。何も考えずに上からパクってMODEの名前を書き換えれば、今回の問題は直るんですけど、それだとどうして直るのか全くわからないんですよ……。

編集者:すずき(2023/09/24 11:52)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年7月9日

ノートPCの発熱を抑える方法 - その2

目次: Windows

前回(2020年6月29日の日記参照)、ノートPCの発熱を抑えるためにCPUのクロック上限を抑える設定をしました。

前回はTurboBoostだけ無効化する方法がわかりませんでしたが、ググっていたら割と簡単にTurboBoostを無効化できることがわかりました。

レジストリエディタで、
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\54533251-82be-4824-96c1-47b60b740d00\be337238-0d82-4146-a960-4f3749d470c7
のAttributesというDWORD値を1から0 or 2に変更します(※)。

すると下記の「プロセッサ パフォーマンスの向上モード」オプションが出現しますので、無効を選択します。


TurboBoostを無効化すると、最大のプロセッサの状態を100% にしても、ベース周波数の1.6GHzまでしか周波数が上がらなくなります。これは良い感じだ。

  • 〜54%: 0.90GHz
  • 〜60%: 0.99GHz
  • 〜65%: 1.10GHz
  • 〜71%: 1.19GHz
  • 〜76%: 1.30GHz
  • 〜82%: 1.39GHz
  • 〜87%: 1.49GHz
  • 〜100%: 3.36GHz → 1.59GHz

(※)私はSurface ProでCPUクロックが最大に張り付くという問題(フォーラムへのリンク)の解決策に載っていたものを見つけたのですが、どうも昔のWindows 8で消えた設定らしい(ASCII.jp : Windows 8.1で消えた詳細な電源管理項目を表示する!より)です。

編集者:すずき(2023/09/24 12:41)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年7月10日

MAD Tower Tycoon楽しい

目次: ゲーム

最近Steamで買った、MAD Tower Tycoon(開発: Eggcode)で遊んでいます。


MAD Tower Tycoon

ビル建築&経営シミュレーションゲームです。プレイヤーはビルを拡張していって、テナントや住居を作ります。テナントには住人やゲストが押し寄せてきますので、住人のストレスを溜めないように、メンテナンス施設を足したり、階段、エスカレーター、エレベーターでうまく捌き、儲けを出して、ビルをさらに拡張させるというゲームです。

The Towerの後継者?

ビル建築&経営シミュレーションの名作はThe Tower(開発: OPeNBooK)だと思います。The Towerは続編が出なくなって久しく寂しかったですが、MAD Tower TycoonはかなりThe Towerに近い作りです。

後追いだけあって基本的にThe Towerより良くなっていますが、残念な部分もあって、

  • 上階に伸ばすときの建設が面倒くさい
  • 中盤から金が余りまくる
  • オフィス、住宅からの変な苦情(人通りが多い)
  • 横移動のストレスがない、もしくは非常に低い
  • エレベーターは速いが、自由度が低い

難易度は最近の風潮で優しめだとしても、最後のエレベーターの劣化は残念です。

エレベーターの変な仕様

エレベーターはThe Towerのキモで、説明書でも詳しく説明していました。MAD Tower Tycoonのエレベーターの場合は、

  • エレベータのカゴ数が最大3で少ない
  • 通過階の設定ができない(降車専用ならある)

特に後者の制限が厳しくて、ゾーン方式(※)エレベーターが実質建設不可能で、高層ビルを作るには厳しい仕様となっています。

(※)エレベーターを複数基用意して、1つ目は1〜5階のみ、2つ目は5〜10階のみなど、一部の階しか止まらないエレベーターを作る方式のことです。現実でも高層ビルでよく見かけます。

むりやりゾーン方式エレベーターを作るとどうなる?

バグなのか仕様なのかわからないですが、MAD Tower Tycoonではバルコニーでフロアをぶち抜いて、スカイブリッジを作ると、どことも繋がらない孤立したフロアを作れます。


普通の四角いビルを作成


バルコニーを作成


バルコニーを破壊すると、スカイブリッジが完成

孤立したフロアにエレベーターだけを設置することで、実質的に乗車降車禁止階にできます。


スカイブリッジ経由で利用してくれない

ところがこの乗車降車禁止エレベータを作っても、なぜか住人は一切利用してくれません。訳が分かりません。どうしたら良いんでしょうか??

オープンブックの紆余曲折

The Tower開発元のOPeNBooKは合併と名前変更を繰り返しています。合併相手は9003, incで、AQUAZONEという熱帯魚育成&水槽シミュレーションで名を馳せたベンダーです。

1993                                          2000
OPeNBooK  ---,    1996                   ,--> オープンブック(The Towerの版権を持つ)
             +--> オープンブック9003 ---+--> シノミクス
9003, inc ---'
1990

Wikipediaを見るとこんな経歴でした。お互い、元の鞘に収まったという感じがします。合併したけどやることがなかったんですかね?

編集者:すずき(2023/09/24 13:07)

コメント一覧

  • わしださん(2020/08/10 22:40)
    オープンブック9003時代に鳥(Pinna?)飼ってました・・・熱帯魚はともかくなぜ鳥飼育ゲーを買ったのか、今となっては心境が分かりません・・・。
  • すずきさん(2020/08/11 18:59)
    鳥のゲームは知りませんでした。色々やってるなあ。オープンブック……。
    あの頃は、PCの解像度がどんどん上がって綺麗になっていて、飼育ゲームとかアクアリウム的な、眺めるタイプの奴が流行ってましたよね。
open/close この記事にコメントする



2020年7月11日

STATIONflow実績コンプリート

目次: STATIONflow

STATIONflowの実績をコンプリートしました。「ラッキーセブン」と「東京」は自動化マクロを組まないと取れませんでした。


STATIONflow実績コンプリート

本来、このゲームにハマって色々なマップをずっと遊んでいたらいつのまにか取れていた、というタイプの実績ですが、申し訳ないことに、私はそこまでの情熱がなかったです。

ゲームやったらわかりますけど、この2つの実績だけ条件設定が異常すぎます。

  • 1日の利用者数は最大17,000人程度(全出入口&乗り場が最大レベルの駅)
  • 1390万人達成には単純計算でゲーム内時間800日程度
  • STATIONflowの1日は最速でも15分、普通に遊ぶと30分〜1時間くらい
  • 最速でも200時間は必要

実績の条件(総利用者数700万人、1,390万人)がいかに異常かがわかると思います。

自動化

自動化の方法は簡単で、PowerShellでEnterキーを3秒に1回送るマクロを組んで、会社行っている間や夜間に放置するだけです。2週間くらいで取れました。

STATIONflowは放置しても悪いイベントが起きない(=駅が壊れない)優しい仕様になっているため、自動化+放置が可能でしたが、他のシミュレーションゲームだと偶発的に悪いイベントが起きるため、この方法は使えません。

まあ、明らかに製作者の想定した取り方ではないし、こんな方法で実績取っても嬉しくないし、無理に実績取るのは今後はやめておきます。

編集者:すずき(2020/09/09 10:39)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年7月12日

MAD Tower Tycoonコンプリート

目次: ゲーム

MAD Tower Tycoonでゾーン方式のエレベータの作り方を悩んで色々やっていたら、いつのまにかレベル100、実績コンプリートしていました。ゲーム内時間は表示されないので詳しくはわかりませんが、おそらく700日くらい?


MAD Tower Tycoon実績コンプリート

The Towerと比べて色々思うところはありますが、総合的にみれば面白いと思います。

序盤だけ金欠になりやすいですが、難易度はかなり低めですし、ビル建築シミュレーション初めての方にオススメしたいゲームです。

高層ビルを作りたい

MAD Tower Tycoonは住人を追尾する機能があり、ビルの住人が困っていないか把握するのに便利です。基本的には目的地に行って、家に帰る(住人の場合)、もしくはビルから出る(ゲストの場合)だけですけど、大きなビルを作ると変な行動が目立ちます。

  • ビルの端から端まで歩いて、わざわざ遠いエレベーターで乗り換え
  • 近所のレストランを無視して、わざわざ遠いレストランに行く

前回(2020年7月10日の日記参照)も書きましたが、MAD Tower Tycoonはゾーン方式のエレベーターを作る方法がわかりません。今はメンテナンス施設の射程(上下6Fに効果がある)の関係で、7階+8階(※)おきに乗り換え階を作っています。

どうもこの方式だと40階くらいで限界っぽいです。乗り換えに時間が掛かりすぎて、目的地に行くだけで半日費やしている気の毒な住民がいます。彼らはなぜか不満は言いませんが、見ていると不憫です……。

救いとしてはMAD Tower Tycoonはビルの横幅がめちゃくちゃ広く取れるので、45階もあれば、レベル100、五つ星ビルが余裕で作れることです。だけど、やっぱりThe Towerにあやかるなら、100階建て目指したいですよね?

(※)効率重視ならば7F, 14F乗り換えが最適ですが、スカイロビーを作成できるのは15Fからなので、あえて14Fを空きフロアにして、15F乗り換えにしています。

どうしてもThe Towerと比較してしまう

MAD Tower Tycoonは、The Towerとかなり似ているがゆえに、つい比較してしまいます。

良いところ

  • エレベータ乗り換えがロビー階以外でも可能
  • 何度でも乗り継げる(1F → 7F → 15F → 23Fのような乗り継ぎが可能)
  • かなり上の階でも階段で行ける(The Towerは確か4Fくらいしか上らない)

悪いところ

  • エレベータの通過階設定ができない(今、一番困っている制限)※通過階設定はできるが設定が効かないバグ、とのこと(2023/10/20追記)
  • 一度上に行ってから、下に行く乗り換えが不可能(1F → 15F → 7Fみたいな乗り換えはしないようだ)

ゾーン方式のエレベーターが作れたら、高層ビルに効率的に人を運べるようになって、もっと面白くなるはずなのに。もったいないよ〜。

編集者:すずき(2023/10/20 03:51)

コメント一覧

  • わしださん(2020/08/10 22:36)
    The Tower懐かしいですね。
    話題とずれる荒しみたいなコメントになりますが、旧姓でエゴサーチして最も古い自分の名前が出るのが、Geocitiesの他人のサイトに投稿したThe towerのビルでした。小6くらいだったのですが、本名とビル名に「第百ビル」とか付けてて。
    その10年以上後、新卒で会社入って最初の移動先の課長に「第百ビルの人?」って聞かれてびびりました。(会社入って一年くらいは旧姓だったので)
    いまはGeocitiesも閉鎖になったので出てきませんが、いい思い出ではあります。
    ということでとにもかくにも100階建てにしてチャペル建てたくなる気持ちを思い出しました。
  • すずきさん(2020/08/11 18:59)
    小学生でサイトに投稿はスゴイです。そして会社バレしてるのも奇遇というかなんというか。
    The Tower で遊んでいたのは、たしか中学生時代だったと思いますが、当時インターネットとかパソコン通信はさっぱりわからず、ビルを投稿しようという考えが全くなかったです。
    Mad Tower Tycoon も 100階にチャペルを建てられますが、The Tower ほどの重要なポジションではない(集客施設の一つに過ぎない)です。星 3〜4辺りからゲーム性が極端に下がってダレてしまうのも、ちょっと残念なポイントです。
  • 通り縋りさん(2023/10/18 19:08)
    上の記事2023年9月編集という事ですが間違ってます。
    2023年10月現在、正しくは「エレベーターの通過階設定自体は出来るが正確に反映されない」です。
    通過階設定自体は出来る事を確認してますが、特に高速エレベーターに於いて設定が正常に反映されず「通過階にも待ちが発生し停車してしまう」というバグとなっています。
  • すずきさん(2023/10/19 11:17)
    ご指摘ありがとうございます。9月の編集は先頭にリンクを加えただけで、内容は2020年7月に書いたときのままです。わかりにくくてすみません。
    それは良いとして、ご指摘の内容に合わせて修正しておきます。
open/close この記事にコメントする



2020年7月13日

STATIONflow - まとめリンク

目次: STATIONflow

一覧が欲しくなったので作りました。

編集者:すずき(2024/01/13 14:14)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年7月14日

OpenCLとICD

目次: OpenCL

OpenCLは複数のベンダーのデバイスを同時に扱うことができます。ICD(Installable Client Driver)というそうです。ICDはGPUなどのデバイスを制御し、アプリケーションとICDの間にICDローダーが存在します。


アプリケーション、ICDローダー、ICDの関係


Debianでのライブラリ名

Debian TestingではICDローダーとしてocl-icd-2.2.12が使われています。

Debian TestingのICD loader
$ apt-cache search ocl-icd-libopencl1

ocl-icd-libopencl1 - Generic OpenCL ICD Loader

ローダーのソースコードはGitHub(リンク)にあります。

先程、図示したもの以外にもICDはいくつか実装があります。現時点のDebian Testingでは下記が提供されていました。

  • pocl-opencl-icd: 主にCPU向け
  • beignet-opencl-icd: 比較的古いIntel GPU向け
  • intel-opencl-icd: 比較的新しいIntel GPU向け、Testingにしか存在しない
  • mesa-opencl-icd: AMD GPU向け
  • nvidia-opencl-icd: nVidia GPU向け、ソースコードは公開されていない

IntelはICDのソースコードを完全にオープンにしています。NVIDIAは公開していません。AMDもないのかな?

ICDのロード手順

動作を追ってみたいと思います。アプリケーションにはclinfoを使います。ocl-icdは環境変数OCL_ICD_DEBUG=15に設定すると、動作時に詳細なログを出力します。デバッガで追うのと併用するとわかりやすいです。

  • clinfo: clGetPlatformIDs() を呼ぶ
  • ocl-icd: _initClIcd() -> _initClIcd_real() -> __initClIcd()
  • ocl-icd: _find_num_icds(): /etc/OpenCL/vendorsの *.icdファイルを見る(*.soへのパスが書いてある)
  • ocl-icd: _load_icd(): *.soをdlopen()
  • ocl-icd: _find_and_check_platforms(): 後述

ローダーが走査するディレクトリは /etc/OpenCL/vendorsがハードコードされていますが、環境変数OPENCL_VENDOR_PATHで変更できます。

ICDのロードの中心となる処理は _find_and_check_platforms() です。

  • dlsym() でclGetExtensionFunctionAddress() のアドレスを得る
  • clGetExtensionFunctionAddress() でclIcdGetPlatformIDsKHR() のアドレスを得る
  • clGetExtensionFunctionAddress() でclGetPlatformInfo() のアドレスを得る
  • clIcdGetPlatformIDsKHR() でプラットフォーム数とプラットフォームの情報を得る

プラットフォームは説明が難しいですが、OpenCL APIの実体+任意のドライバ固有のデータとでも言いましょうか。変数の型はcl_platform_id * 型です。cl_platform_idは少なくとも先頭のメンバはstruct _cl_icd_dispatch *dispatchでなければなりません。dispatchの後ろには他の情報が入っていても問題ないようです。

cl_platform_idとdispatch

// ocl-icd/ocl_icd_loader.c

static inline void _find_and_check_platforms(cl_uint num_icds) {
  cl_uint i;

...

    cl_platform_id *platforms = (cl_platform_id *) malloc( sizeof(cl_platform_id) * num_platforms);
    error = (*plt_fn_ptr)(num_platforms, platforms, NULL);

...

    for(j=0; j<num_platforms; j++) {
      debug(D_LOG, "Checking platform %i", j);
      struct platform_icd *p=&_picds[_num_picds];
      char *param_value=NULL;
      p->extension_suffix=NULL;
      p->vicd=&_icds[i];
      p->pid=platforms[j];    //★★pid = platform IDのことらしい

      /* If clGetPlatformInfo is not exported and we are here, it
       * means that OCL_ICD_ASSUME_ICD_EXTENSION. Si we try to take it
       * from the dispatch * table. If that fails too, we have to
       * bail.
       */
      if (plt_info_ptr == NULL) {
        plt_info_ptr = p->pid->dispatch->clGetPlatformInfo;    //★★dispatchメンバが存在することを前提としている

      
// ocl-icd/khronos-headers/CL/cl.h

typedef struct _cl_platform_id *    cl_platform_id;


// ocl-icd/(build-dir)/ocl_icd_loader_gen.h

struct _cl_platform_id { struct _cl_icd_dispatch *dispatch; };    //★★dispatch以外は特に規定がなさそう


// ocl-icd/(build-dir)/ocl_icd.h

struct _cl_icd_dispatch {
#ifdef CL_VERSION_1_0
  CL_API_ENTRY cl_int (CL_API_CALL*clGetPlatformIDs)(
    cl_uint          /* num_entries */,
    cl_platform_id * /* platforms */,
    cl_uint *        /* num_platforms */
  ) CL_API_SUFFIX__VERSION_1_0;
#else
  CL_API_ENTRY cl_int (CL_API_CALL* clUnknown0)(void);
#endif

#ifdef CL_VERSION_1_0
  CL_API_ENTRY cl_int (CL_API_CALL*
  clGetPlatformInfo)(
    cl_platform_id   /* platform */,
    cl_platform_info /* param_name */,
    size_t           /* param_value_size */,
    void *           /* param_value */,
    size_t *         /* param_value_size_ret */
  ) CL_API_SUFFIX__VERSION_1_0;
#else
  CL_API_ENTRY cl_int (CL_API_CALL* clUnknown1)(void);
#endif

...

//★★こんな調子で関数ポインタの定義が延々と続く

先頭のdispatchはたくさんの関数ポインタが並んだ巨大な構造体です。アプリケーションから見るとOpenCLのAPIはocl-icdが提供しているように見えますが、ocl-icdのAPI実装はdispatchの関数ポインタを呼ぶラッパー関数であり、関数ポインタと、OpenCL API実装の本体を提供するのは各ICDの役割です。

編集者:すずき(2023/09/24 11:57)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2020年7月15日

GCCを調べる - その16 - 自動ベクトル化を有効にする

目次: GCC

GCCには自動ベクトル化(tree-vectorize)機能があります。ループ処理を自動的にSIMD命令に置き換えるために使われているようです。現状のGCCが可変長のベクトル長に対応しているかどうかはわかりません。未対応ならば可変長のベクトル長に対応する実装が必要になりますが、非常に難しそうです。

可変長のベクトルの扱いはひとまず横に置くとして、RISC-Vのベクトルを「とても長い固定長のSIMD」とみなして自動ベクトル化を動かします。

自動ベクトル化を有効にするコード

// gcc/config/riscv/riscv.c

/* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES.  */

static unsigned int
riscv_autovectorize_vector_modes (vector_modes *modes, bool)
{
  if (TARGET_VECTOR)
    {
      modes->safe_push (V64SImode);
      modes->safe_push (V32SImode);
    }

  return 0;
}

...

#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES riscv_autovectorize_vector_modes

自動ベクトル化を有効にする方法は簡単で、これだけです。

テスト用のint配列をコピーする関数

void *cpy(void *dst, const void *src, int n)
{
	int *d = dst;
	const int *s = src;
	int i;

	for (i = 0; i < n / sizeof(*d); i++) {
		d[i] = s[i];
	}

	return dst;
}

この関数がベクトル化あり、なしでどのように変わるか見ます。

自動ベクトル化の結果

//★★自動ベクトル化、あり

                d[i] = s[i];
   100b8:       1202e007                vlw.v   v0,(t0)
   100bc:       10038393                addi    t2,t2,256
   100c0:       f0038793                addi    a5,t2,-256
   100c4:       10028293                addi    t0,t0,256
   100c8:       0207e027                vsw.v   v0,(a5)
        for (i = 0; i < n / sizeof(*d); i++) {
   100cc:       fee296e3                bne     t0,a4,100b8 <cpy+0x44>
   100d0:       00661293                slli    t0,a2,0x6
   100d4:       02568963                beq     a3,t0,10106 <cpy+0x92>
   100d8:       959a                    add     a1,a1,t1
   100da:       932a                    add     t1,t1,a0
                d[i] = s[i];
   100dc:       0005a383                lw      t2,0(a1)


//★★自動ベクトル化、なし

                d[i] = s[i];
   10080:       0005a303                lw      t1,0(a1)
        for (i = 0; i < n / sizeof(*d); i++) {
   10084:       0591                    addi    a1,a1,4
   10086:       0291                    addi    t0,t0,4
                d[i] = s[i];
   10088:       fe62ae23                sw      t1,-4(t0)
        for (i = 0; i < n / sizeof(*d); i++) {
   1008c:       fe759ae3                bne     a1,t2,10080 <cpy+0xc>
        }

        return dst;
}
   10090:       8082                    ret

ソースコードではベクトル型を使っていませんが、自動ベクトル化により256バイト(=64要素)ずつ処理され、vlw.v, vsw.v命令が使われるようになったことがわかります。

編集者:すずき(2023/09/24 11:52)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2020年7月8日 >>> 2020年7月17日
link もっと後

管理用メニュー

link 記事を新規作成

<2020>
<<<07>>>
---1234
567891011
12131415161718
19202122232425
262728293031-

最近のコメント5件

  • link 21年3月13日
    すずきさん (03/05 15:13)
    「あー、このプログラムがまずいんですね。ご...」
  • link 21年3月13日
    emkさん (03/05 12:44)
    「キャストでvolatileを外してアクセ...」
  • link 24年1月24日
    すずきさん (02/19 18:37)
    「簡単にできる方法はPowerShellの...」
  • link 24年1月24日
    KKKさん (02/19 02:30)
    「追伸です。\nネットで調べたらマイクロソ...」
  • link 24年1月24日
    KKKさん (02/19 02:25)
    「私もエラーで困ってます\n手動での回復パ...」

最近の記事3件

  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
  • link 24年3月19日
    すずき (03/20 02:52)
    「[モジュラージャックの規格] 古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタク...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 03/26 03:20