コグノスケ


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

link もっと前
2021年10月4日 >>> 2021年9月21日
link もっと後

2021年10月4日

Might and Magicファミコン版 - まとめリンク

目次: Might and Magicファミコン版

TASに挑んだ記録。

解析したときの情報。その他。

リンク集

Might and Magicの攻略、解析の参考になるサイトです。

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

コメント一覧

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



2021年9月30日

携帯の遍歴

日記を漁って携帯の遍歴を書き出してみました。日記を書く習慣がなかった頃の機種や時期は不明です。

J-PHONE, Vodafone
  • 不明(2000年くらい?): SHARP J-SH04辺り?
  • 不明(2002年くらい?): TOSHIBA J-T06辺り?(ストレートだった気がする)
NTTドコモ、ガラケー
  • 2004年8月: Fujitsu F506i
  • 2005年6月: Fujitsu F506iマイク故障で交換
  • 2006年 ?月: NEC N902iS
  • 2008年 ?月: NEC N902iSのバッテリー交換
  • 2010年7月: Panasonic P-03B
NTTドコモ、スマホ
  • 2011年7月: Sony Ericsson Xperia acro SO-02C
  • 2014年3月: SHARP AQUOS PHONE ZETA SH-01F
SIMフリー、スマホ
  • 2016年11月: ASUS Zenfone 3 Deluxe
  • 2021年4月: Google Pixel 4a

(基本的には)長く使っていた機種は気に入っていた機種です。ガラケー時代はいずれも良い機種で、バッテリーが死ぬまで使ってました。最後のP-03Bだけ1年しか使っていませんが、不満があったわけではなく、知人に携帯を譲るため手放しました。たしか。

スマホ時代は国内メーカーの質は明らかに落ちました。SO-02Cはソツなく良かったんですけど、ストレージが少なすぎで買い替え直前は容量不足で挙動不審でした。SH-01Fは性能良いものの、電池がなくなるのが早く、本体が熱すぎでした。この機種で懲りてAndroidハイエンド機を買わなくなりました。

今になって調べてみたところ、この2機種はマシな部類だったようで、富士通ARROWSのように「カイロ機能搭載」「電話ができない」「メールがこない」など、怨嗟にまみれたレビューが未だに残っている機種もあります。悲惨です。

日本だけ異常にiPhone普及率が高い理由って、国内メーカーが2010年代初頭にやらかしたから……!?と思ってしまいました……。

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2021/10/08 16:56)

コメント一覧

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



2021年9月28日

マルチコアのブート処理

目次: RISC-V

メインCPUからサブCPUを起こすとき基本的には、

  • CPUのID(RISC-VであればCSRのmhartid)を見て、自身がメインかサブかを知る
  • サブ側は共有RAMをポーリングなどで見張り、メインCPUからの起動司令を受け取るまで待つ
  • メイン側は共有RAMに値を書いてサブCPUに起動司令を送る

RAMの初期値が不定であると仮定すると、サブCPUが下手にポーリングすると、不定値によって条件が成立してしまい、メインCPUからの起動司令がないのに勝手に起動してしまう事態に陥ります。

素朴な実装

先程書いた基本的な構造を素直に書くとこんなコードになるでしょう。

素朴なマルチコアのブート

/* メインCPUはHARTID=8, サブCPUはHARTID=0...3とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	int boot_wait;
	int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メインCPUが実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		init_core[i].boot_wait = 1;
	}
}

/* サブCPUが実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	while (!init_core[hartid].boot_wait) {
		/* busy loop */
	}
}

残念ながらこのコードは正常に動作しません。共有RAMつまりinit_core[hartid].boot_waitの値が起動直後から != 0だったとき、boot_sub() はboot_main() からの起動司令を待つことなく起動してしまうからです。

不定値への対処

共有RAMの不定値に対処する方法を考えます。基本的にはサブCPUが変数を初期化(boot_wait = 0)してから待ちに入れば良いのですが、新たな問題が生じます。メインCPUとサブCPUの実行順序はどちらが先という保証はないため、

  • メインCPUからの起動司令boot_wait = 1
  • サブCPUで変数を初期化boot_wait = 0

以上の順で実行されるとメインCPU側の起動司令が消されてしまい、ハングアップする可能性があります。この問題の回避のため、変数を1つ追加し、サブCPUのブートが終わるまで、メインCPUは繰り返し起動司令を送るように変更します。

  • 変数を2つ用意する(boot_wait, boot_done)
  • メイン: boot_done = 0
  • メイン: サブから応答(boot_done != 0)があるまで、boot_wait = 1を書き続ける
  • サブ: boot_wait = 0
  • サブ: boot_done = 0
  • サブ: boot_wait == 0なら待つ
  • サブ: boot_done = 1

先程書いた基本的な構造を素直に書くとこんなコードになるでしょう。

不定値への対処を入れたコード

/* メインCPUはHARTID=8, サブCPUはHARTID=0...3とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	int boot_wait;
	int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メインCPUが実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		init_core[i].boot_done = 0;
		while (!init_core[i].boot_done) {
			init_core[i].boot_wait = 1;
		}
	}
}

/* サブCPUが実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	init_core[hartid].boot_wait = 0;
	init_core[hartid].boot_done = 0;

	while (!init_core[hartid].boot_wait) {
		/* busy loop */
	}
	init_core[hartid].boot_done = 1;
}

残念ながらこのコードも正常に動作しません。共有RAMへの値の反映が他のCPUに即座に見えること(アトミック性)を暗に期待しているからです。

アトミック性への対処

今日のマルチコアシステムでは、boot_wait = 0としたときに、他のCPUにも即座に同じ値が見えているとは限りません。主な要因としては、

  • コンパイラによる並べ替え
  • CPUのパイプライン
  • CPUのデータキャッシュ、ライトバッファ

などがあります。通常の変数への代入、参照が他のCPUに即座に値が見えないことにより、おかしくなるパターンはいくつか考えられそうですが、ありがちなパターンとして、

  • サブCPU 0が起動したboot_done = 1
  • メインCPUにboot_done = 1が伝わらず、サブCPU 1の起動指令がいつまでも送られない

以上の順で実行されるとメインCPU側が起動司令を送らないまま、サブCPU側も何もできずハングアップする可能性があります。この問題の回避のため、通常の変数への代入、参照ではなく他のCPUにも値が見えるように初期化、代入(アトミックアクセスする)必要があります。

従来C言語でアトミックアクセスを行うためには、実装対象アーキテクチャの知識やアセンブラの記述を必要とするなど、やや困難が伴いました。ですがC11でアトミックアクセス用の定義stdatomic.hが追加されたことで、アトミックアクセスはかなり楽になりました。素敵ですね。

ひとまず速度を全く気にせず、全てのアクセスをアトミックアクセスに入れ替えると、こんなコードになるでしょう。

アトミック性への対処を入れたコード

/* メインCPUはHARTID=8, サブCPUはHARTID=0...3とする */

#define HARTID_MAIN         8
#define HARTID_SUB_START    0
#define HARTID_SUB_END      3

#define HARTID_MAX          9

struct {
	atomic_int boot_wait;
	atomic_int boot_done;
} init_core[HARTID_MAX] = {};

int get_hartid(void)
{
	int i;
	__asm__ volatile("csrr %0, mhartid" : "=r"(i));
	return i;
}

/* メインCPUが実行する */
void boot_main(void)
{
	for (int i = HARTID_SUB_START; i < HARTID_SUB_END; i++) {
		atomic_store(&init_core[i].boot_done, 0);
		while (!atomic_load(&init_core[i].boot_done)) {
			atomic_store(&init_core[i].boot_wait, 1);
		}
	}
}

/* サブCPUが実行する */
void boot_sub(void)
{
	int hartid = get_hartid();

	atomic_store(&init_core[hartid].boot_wait, 0);
	atomic_store(&init_core[hartid].boot_done, 0);

	while (!atomic_load(&init_core[hartid].boot_wait)) {
		/* busy loop */
	}
	atomic_store(&init_core[hartid].boot_done, 1);
}

C11のアトミックアクセスは何も指定しない場合、一番制限の強い(= 確実に他のCPUに見えるものの、アクセス速度は遅い)memory_order_seq_cstアクセスになります。マルチコアのブートを行うにあたって、常に制限が強いアクセスは必要ありませんが、とりあえずこれで動くはず。

編集者:すずき(2022/04/04 06:05)

コメント一覧

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



2021年9月26日

xtermの256色端末

まれにxtermの256色指定エスケープシーケンスに対応していない端末があってvimの表示が変な色になってしまいます。チェック用のスクリプトを作っておきました。単純に背景色を変更するエスケープシーケンスと、空白文字、色を元に戻すエスケープシーケンスを連打するだけです。

xterm 256色指定エスケープシーケンステスト用スクリプト

#!/bin/sh

ESC_ORG="\e[0m"

print_colors()
{
	for i in ${*};
	do
		printf " %3d\e[%dm  " ${i} ${i};
		echo -n ${ESC_ORG}
	done
	echo
}

print_xterm_colors()
{
	for i in ${*};
	do
		printf " %3d\e[48;5;%dm  " ${i} ${i};
		echo -n ${ESC_ORG}
	done
	echo
}

echo "System colors (ESC[Nm):"
print_colors `seq 40 47`

echo
echo "xterm 256 colors (ESC[48;5;Nm):"
for i in `seq 0 8 248`;
do
	j=`expr ${i} + 7`
	print_xterm_colors `seq ${i} ${j}`
done

実行するとこんな感じになります。


スクリプトの実行結果

対応していない端末だとこうなりますと言いたいところでしたが、対応していない端末が見当たりませんでした。前はあった気がするんだけどなあ……?

編集者:すずき(2021/09/29 01:32)

コメント一覧

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



2021年9月23日

耳年齢チェック

何kHzの音まで聞こえるかテストするサイト、聞こえチェック | Panasonic が、以前Twitterでちょっと話題になりました。

私の場合15kHzまでは聞こえますが、それ以上(17kHz, 19kHz)は全く聞こえません。鳴ってんのか?これ??

測ってみよう

まずブラウザの影響を排除するため、上記のサイトから音源をダウンロードします。WavではなくMP3ファイルでした。

直接オーディオプレイヤーで聞いても15kHz以外は聞こえません。ブラウザのせいじゃなかった。私の耳は全くあてにならないので、オシロスコープにご登場願います。


15kHz再生時の波形


17kHz再生時の波形


19kHz再生時の波形(グラフはキャプチャし忘れて17kHzのまま。右下の周波数表示が19kHzを示している)

いやあ、バッチリ綺麗にSin波が鳴ってます。私は全く聞こえませんね、これが老いかぁ……。

編集者:すずき(2021/09/29 00:21)

コメント一覧

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



link もっと前
2021年10月4日 >>> 2021年9月21日
link もっと後

管理用メニュー

link 記事を新規作成

<2021>
<<<10>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント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月19日
    すずき (03/20 02:52)
    「[モジュラージャックの規格] 古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタク...」
  • link 23年4月10日
    すずき (03/19 11:48)
    「[Linux - まとめリンク] 目次: Linuxカーネル、ドライバ関連。Linuxのstruct pageって何?Linu...」
  • link 24年3月18日
    すずき (03/19 11:47)
    「[画面のブランクを無効にする] 目次: LinuxROCK 3 model CのDebian bullseyeイメージは10分...」
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 www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 03/20 02:52