ごらくらいふ

プログラミングしたりゲームしたり

OSXやiOSにおけるスレッドのスタックサイズ

最近、ご無沙汰になっていたので軽いものを。

iOS関連のトラブルシューティングを行っている際に、スタックのアドレスか、そうでないかを気にする場面があった。

「そういえば、スタックの大きさってなんだ?」 ドキュメントによれば、メインスレッドには特別に多く割り当てられるらしい。

OSX(いまや macOS ?)では 8MBiOS においては 1MB だそうだ。iPadOSもiOSに準じていそうだ。

そして、サブスレッドには 512KB まで割り当て可能のように読める。最小は 16KB で、 4KB 単位で増やすことができるという。

Thread Management

ここから雑多に考えてることを書き出している。理路整然とはしていない。

メモリに対するおおまかなイメージは、単一のスレッドが単一の仕事をする場面における印象しかなかった。 ヒープもスタックも同一の主記憶装置(メモリ)を使い、膨大なメモリ空間の先頭側から自由に使える空間をヒープメモリ、メモリ空間の末尾側から使われ積まれていくものをスタック領域と呼ぶイメージだった。 スタックオーバーフローはこのヒープとスタックがぶつかったときに起きるような、そんな認識でいた。

仕事で付き合うコンピューターはマルチスレッドで動いているものだし、単一のプロセスに集中するのではなく、多くのプロセスにいい感じに計算リソースを割り当てて動いている。 ということは、あれこれをごちゃ混ぜにしては管理がし辛いはずだ。

求められる仕事の数に対して、レジスタの数は限られている。 スタックポインタはスタック操作のたびにアドレスを変えるのだから、いろんなプロセスが同じスタック領域を共有していては扱うアドレスやデータを間違えないことは不可能だろう。 スレッドが扱うプロセスを変えるたびに、レジスタの状態は保存され(また、復元され)ているべきだろう。 保存・復元を用意にするためには、プロセスごとに使用するメモリの領域が予約されていればいいのだろう。 雑多に混ざっているよりは、「このプロセスが使うメモリの(スタック)領域はこの範囲」と明らかになっていれば、扱いやすいことは想像に難くない。

スレッドごとに決められたスタック領域を割り当てられるもの、という認識が持てて今回の調べ物は良かった。

FFORIGINの本編ストーリーをクリアした

さる 2022-08-29 に FF ORIGIN (Stranger Of Paradice Final Fantasy Origin) をクリアしたことをご報告します。

www.jp.square-enix.com

FF ORIGIN は 2022-03-18 に発売された、ファイナルファンタジー 第一作の世界観を基盤とした、ダークファンタジーRPGです。

アーリーアクセス権をつかんで、発売日前に遊んだのですが、当時は他に優先しているゲームがあって積みゲーにしてしまったんですね。 で、2022-07-24 にDLC竜王バハムートの試練」配信記念の公式生放送があり、諸々アップデートも入るとのことだし、いっちょやってみるかと復帰(?)した次第です。(ついでに配信しながら遊ぼうと)

www.youtube.com

感想

クリア直後の感想ツイート↓

FF ORIGIN ストーリークリア(アプデ後)での感想だけど、攻略済みミッションの再突入をしなくて良かったし、ステージもボスもバリエーション豊かで50時間遊んでた。立派なアクションRPGだ。

https://twitter.com/Yajamon/status/1564460031298654208

はじめにガーランドと戦い、クリスタルへ赴き4体のカオスと戦い、混沌の闇と戦う。FFの構造をなぞりながら、各ダンジョンには各ナンバリング作品から舞台を拝借したりしている。 だから、第一作を基盤としているどころか、ファイナルファンタジーの世界観を寄り集めた世界観のゲームだったんだなぁと思い至っています。

本編ストーリーをクリアした回↓

youtu.be

以後は、難易度CHAOSを進めてDLCを目指していきます。 本格的にハクスラを堪能する状況になったわけですね。

以下はプレイリストになります。

www.youtube.com

ObsidianのZettelkastenプラグインはユニークノートクリエイターになった

  • Obsidian v0.15.8 で気づいた
  • コアプラグインである ZettelKastenプレフィクサー は、 ユニークノートクリエイター に名前を改めた

移行作業はとくにない

設定内容に変化はなかった

  • ディレクトリもそのまま
  • フォーマットもそのまま
  • テンプレートもそのまま
  • ショートカット設定もそのまま

通常、表に出て来ない要素

  • コマンドIDは zk-prefixer のままらしい

リンク

その「ユニークノートクリエイター」の振る舞いをちょっと調べたので Zenn.dev に書いた。

zenn.dev

コマンドエイリアスとは、自作のプラグインのこと。

yajamon.hatenablog.com

Obsidianとは、Markdownに焦点を当てたメモツールのこと。

obsidian.md

書き捨てストレッチ:素数を判定するツール

「もう6月も終わるし、なんかネタ出さないとな」とデレステのイベントを走ってたら素数っぽい数字が見えた。

そういえば素数判定するコードは書けるはずだけど、すぐ参照できる場所にコードがないな…?

書いてみた

書き捨てだから(免罪符)深いこと考えない実装をしてみた。

/**
 * 素数判定スクリプト
 * @param {number} value 素数判定したい数値。0以上の整数を期待する。
 * @return {boolean} 素数であれば `true`。
 */
function isPrimeNumber(value) {
  if (value < 2) {
    return false;
  }
  let element = 2;
  while (element * element <= value) {
    if (value % element === 0) {
      return false;
    }
    element += 1;
  }
  return true;
}

Webツールとしてはいつもの GitHubホスティング

yajamon.github.io

factor コマンド使えば良い

こんな実装し~なくても。ってやつ。

factor というコマンドはパラメータの値を素因数分解してくれる。 この結果を確認すれば、素数か判断できる。

factor 180007
# 180007: 180007  
factor 10
# 10: 2 5

チラシの裏

  • 素数は英語で「prime number」というらしい
  • 合成数は英語で「composite number」というらしい

新和英大辞典 第5版 研究社より

PS5版を買うかPC版を買うか悩むときの評価軸

欲しいゲームが PS5 や Steam などマルチに展開している場合、どこで買うか迷ってしまう。 例えば今、テイルズオブアライズを ウィークエンドセールのSteam で買うか ゴールデンウィークセールのPS5 で買うか迷っている。

答えは出ていないが、プラットフォームを決定する評価軸があるはずなので書き出してみる。

評価軸

販売先

  • 前提として、販売対象のプラットフォームが検討対象になる
  • 単一のプラットフォームにしかない場合、ただ買えば良い

値段

  • ストアの恒常的な値下げ
    • PS Store の場合、 Hits になったソフトが安くなったりする
  • セールで安い
    • 今すぐやりたいほどではないが遊ぶつもりのもの
    • 安いときに買う
  • 即買いラインを下回っている
    • プラットフォームごとに買う場合もある

プラットフォームによる違い

  • プラットフォームのスペック
    • PS4 より PS5
    • PC と PS5
      • SSDストレージの大きさ
      • GPU性能
  • ソフトウェアの可搬性
    • PC版は基本的に端末を新しくしてもなんとかなる
    • PS5版は Sony が互換性を提供する限り遊べる
  • 操作方式の違い
    • PS5 はコントローラー操作が基本
    • PC はマウス・キーボードがあって当然で、コントローラーも使える

ストアの違い

  • 表現規制の差異
    • PS版は独自な表現規制が施されがち
    • Steam版の方に規制が施される場合がある
    • 事前に情報が得られるなら参考にする
  • 再ダウンロードのサポート
    • Steam
      • パブリッシャーがSteamに卸している限り保証される
    • PS Store
      • コンソールの場合、ほとんどが長期にわたって継続して提供される

ゲームと直接関係ない部分の理由

  • ゲーム配信がしたい
    • リソース消費の激しすぎるゲームをPS5に切り離す

Modの需要

  • 楽しみたい内容に Mod が含まれるなら PC 版しかない

買うこと自体を延期するか

ちゃぶ台返しなので末尾に……。

  • 絶対ネタバレされたくないか
  • すでにカートに突っ込んだゲームの数々
  • 積んでるゲームの数々
  • セール待ちをするか

ふとresult.tsを更新した

Changelog

  • バージョン 0.3.0 になりました。

Enhancement

  • ok<T>(value: T) という関数を追加しました。
  • err<E>(error: E) という関数を追加しました。

Deprecated

  • Ok<T>(value: T)
  • Err<E>(error: E)

www.npmjs.com


経緯

先日、 WSL2 環境を Ubuntu 22.04 LTS に移行した。 環境が新しくなると整えたくなるもので、この移行に伴って dotfiles の整備をはじめた。

以前からなんとなく気になっていた efm-langserver を使ってみようと思い立った。 これは、 ESLint などの linter が吐き出すメッセージを Language Server Protocol (以下 LSP) に載せ替えてくれるLanguage Serverだ。 ESLint+prettierの lint結果をLSP経由で扱えるだけでも便利だし、 zenn.dev に投稿する文書を textlint で校正もできるようになる。

これの実験にちょうどよいのが result.ts だった。 ESLint , prettier, TypeScript を使っていて、ボリュームも小さいからだ。

result.ts とは

ここで一旦説明をする。 result.ts は Rust の Result を真似て書いてみたものである。

export type ResultOk<T> = {
  isError: false;
  value: T;
};
export type ResultErr<E> = {
  isError: true;
  error: E;
};

export type Result<T, E> = ResultOk<T> | ResultErr<E>;

https://github.com/yajamon/result.ts/blob/75e33b52193f5f16e99d53b43b388616ab1967b6/src/main.ts#L1-L9

  • こんな具合に、値かエラーを包んでいるオブジェクトは共通して isError を持っており、これを if でチェックするとスコープの中で型が確定できる。
  • 個人的なこだわりは、 class を使わず、ピュアなオブジェクトに包むことである。

シグネチャへの違和感

result.ts だが、最終更新を確認すると2年以上前である。 これほど時間が経つと、当時とコードに対する感覚も変わってくる。

ふとコードを見ると違和感があった。

export const Ok: <T>(value: T) => ResultOk<T> = v => ({
  isError: false,
  value: v
});
export const Err: <E>(error: E) => ResultErr<E> = e => ({
  isError: true,
  error: e
});

https://github.com/yajamon/result.ts/blob/75e33b52193f5f16e99d53b43b388616ab1967b6/src/main.ts#L13-L20

TypeScript なのに関数がパスカルケース ( Ok(v) , Err(e) ) なのだ。 当時の感覚としては、Rust の タプル構造体 を生成してるように見えて面白いからといった所だろうが、いくらなんでも寄せすぎた。

Rust においては、あくまで enum Result<T,E> のいち構造体様の生成であり、関数ではない。

doc.rust-lang.org

TypeScript / JavaScript において関数のシグネチャは、少なくともパスカルケースは主流ではない。 そしてオブジェクトの生成は new Ok(value) などとするものだ。なんとも上記のコードでは気持ち悪さを感じる。

ということで ok(v)err(e) を生やすこととした。

現行バージョンは 0.2.x だし、シグネチャをまるっと変えても良いかなと思ったけれど、「わざわざ破壊しなくてもいいか」と思いとどまった。 代わりに @deprecated アノテーションを付与した。

書き捨てストレッチ:縦書きジェネレーターを書いてみた

なんか作った感を得たくて、書き捨てツールを書くストレッチをした。

シリーズ物というわけではないが(?)、今回のお題は縦書きジェネレーター。

縦書きジェネレーター

書き捨てストレッチでは、ひとまず単体の HTMLファイル で完結させることにしている。 Node.js も TypeScript も関係ない、原始的なものを書きたくなることって、あるよね。

実際のところ、html内埋め込みで書くのは面倒である。 補完が効いてるような効いてないようなって感じだし、jscss の単体ファイルでは起こらないようなインデントのわちゃわちゃが起きて、開発体験は眉がハの字になってしまう。

それでも、なんも気にせず書くのは楽しい。 画面上に説明書きも用意されてないし、振る舞いのオプションはないし、期待していない入力への手当もない。 しかしながら目的は(自分目線で)間違いなく達成されている。

「ほしいな」「つくった」「うごいた」これで心が少し潤う。