週記 2022/01/10~2022/01/16

2022/01/10

16時ごろに起きる。

起きたので何か食べたいけど、うどんを作るのも面倒くさいので、牛乳をかけるだけのフルグラを食べる事にした。うまい

テレビをつけると、相撲の中継をしていたのでなんとなく眺めていた。ルールが単純なので、他のスポーツ中継より見やすいな。相撲中継が終わって、適当にチャンネルを回してみたけどなんか微妙だったので、そのままテレビを消した。

知覚ハッシュで画像を検索するやつをいじる。ライブラリ側ができてきたので、実戦投入するためにコマンドを作り始めた。最近メジャーアップデートがあったclapを使ってコマンドライン引数の処理を書いていたけど、デフォルト値にPathBufDisplayを実装していない)が使えなくて早速辛い気持ちに。文字列で受け取ったら良いけど、なんだかなぁ…

いつの間にかベンチマークの結果がめっちゃ良くなっていて、どこで良くなったのか調べてみたけど、良く分からず。ぐぬぬ

Windowsでいい感じに使えるプロファイラが欲しいけど、いまいちまとまった情報が見つけられず。WSLでLinux用の物が動くかもだけど、それはそれで環境が整備できていないので、まず舗装が必要。ぐぬぬ…(2回目)。Visual Studioのおまけが結構良かった記憶があるけど、ゲームを入れる為にアンインストールしてしまったし…

2022/01/11

17時ごろに起きる。

目覚まし時計が鳴るように設定して寝てみた。目覚ましが鳴り始めると意識は復活する(音を聞いてる)けど、それ以上が動き出さなくて、そのまま二度寝

画像を検索するやつのコマンドの続きを書く。画像のハッシュを溜めていて、フォルダー内の画像のハッシュを一気に追加する処理を書いた。一気に大量の画像を処理するので、「マルチスレッド処理にすると早くなるだろう。ぐへへ」という考えで、rayonを使って並列処理を書いてみたけどこれが難しい。ハッシュを計算してくれるHasherを用意して、それの参照を各スレッドに渡すだけの簡単なお仕事だと思っていたけど、実はHasherSyncを実装していなくて参照を渡せなかった。ぐぬぬ…。結局、処理する画像毎にHasherを初期化して並列にしたけど、なんか気持ち悪いな…

2022/01/12

11時ごろに起きる。

久しぶりに出かけるので、適当な服装で出かけてみたものの、服の感覚が秋から更新されておらずクッソ寒い。出発から到着までは特に感じなかったけど、「それ寒くない?」と指摘されてからはなんだか寒く感じた。なんなんだ

久しぶりにファミリーマートへ行ってファミチキを食べる。やっぱうまえな。ついでに買ったいい感じのメロンパンは、明日のおやつ。

有吉の壁を観る。ドンキも面白かったけど、最後のギルティフラッシュ(チョコレートプラネット)が最高だった。ここ最近で1番面白い。

昨日のHasherを初期化するコストが気になったので、ベンチマークを取ってみた。どうやら数十ns程度で初期化できていて、ほとんど無視できそう。それなら、並列化が結構お気楽にできそうなので、色々試してみよう。

2022/01/13

15時ごろに起きる。

昨日久々に外を歩き回ったからか、足が筋肉痛でピンチ。

昨日ファミリーマートで買ったメロンパンを食べる。明日に食べても良いんじゃないかと思っていたけど、消費期限を見たら今日まででギョッとする。パンは生物だな…

相撲中継を見る。今回は取組の進行をしたりする呼出という仕事に注目しているそうで、名前の通り力士を呼び出したり、準備が遅い時に拍子木を叩いて催促したりと、呼出の仕事を知る事ができた。

最近、BitTorrentでシードしているRaspberry Pi OSのイメージが人気なのか、アップロード量が増えている。(1日1GB程度)

昨日の並列化の手法を色々と試してみる。まず、rayonの他にtokioを使った並列化を試してみた(画像ひとつ毎にtokio::spawn()する)けど、対象の画像を一気に全部読み込もうとするので、メモリ使用量が大変な事になってしまいボツ。次に、コア数分のスレッドを生やして、チャンネルで仕事を送信する手法をstdで実装してみた。メモリを使い過ぎずに早くなって好感触。ただ、rayonを使った実装と比べるとスレッドの初期化やら下準備のコードが多くなる(それはそう)ので、どっちが良いか結論は出ず…

書いたプログラムのボトルネックを探るべく、プロファイラを色々調べる。Linux環境だとperfが使えるけど、WSL環境だと微妙らしい。過去にAMD uProfをWindowsで使ったのを思い出したので、今回のプログラムを食わせてみたけど、関数とかの情報(シンボル)が何も出なくて使えなかった(コンパイルオプションは大丈夫なはずだけど…)。以前他のものをプロファイルした時は色々出てきたので、何かが変わってしまっているぽいけど、調査する元気も技術力もなく…

明日は早起きなのに、真夜中にこんな日記を書いて良いのか…

2022/01/14

10時ごろに起きる。

出かける直前になって財布が見つからない。現金はその辺にあるので大丈夫だけど(大丈夫ではない)、財布にICOCAを入れているので、これが無いと電車に乗るのが若干面倒になる…。5分程度探したけど見つからなかったので、捜索を打ち切り千円札を握りしめて出発した。

外は雪が積もっていて、気を抜いたらすぐに滑って転んでしまいそう。恐ろしい。なんとか駅まで来れたけど、乗る予定の列車には間に合わず、目の前で見送る事になった。次の列車を待とう…

次に来た列車に乗り込むと、「この列車は次の駅で終点だよ!」という放送が流れて、本当に次の駅で終わってしまった。え〜!と思ったけど仕方ないので下車。20分で1駅しか進めていない。乗ってきた列車は反対側の線路に移動して、ものすごい勢いで来た方向へ戻っていった。ぐぬぬ

この時点で遅刻が確定。確定してしまえばもうお気楽で、駅の構内をうろついたり、雪が積もった線路の写真を撮ったりしていた。

最終的に20分程度遅刻したけど、先方も遅れていて大事にはならず。

用事を済ませて、昼食を買いに行く。マクドナルドへ行く機運が高まっていて、具体的には”黒胡椒ガーリックナゲット”が目当て。罪深い名前だ。せっかくなので期間限定のバーガーも食べたくなり、サムライマックとやらの”燻製風マヨ トリプルベーコン肉厚ビーフ”を注文。

急いで家に帰り実食。とても良い(良い)

f:id:hotate29:20220115041713j:plain

画像の知覚ハッシュを検索するやつを作る。色々試した結果、rayonを使って並列化する事に決めた。元のコードと形が近いのと、自作スレッドプールやtokioで並列化したものと速度がそんなに変わらなかったから。

並列処理をする際のスレッド数を制限したくなり、rayonの諸々を調べる。rayonのドキュメントを読むと「ThreadPoolBuilderを使うとローカルのスレッドプールと、グローバルなスレッドプールを初期化できるよ!!」的なことが書いてあり、今回はグローバルなスレッドプールを作りたいので、そのように実装してみた。

しかし、実行してみると「もう初期化されてるよ!」というエラーが出てしまい動かなかった。main関数の最初の方で初期化しているので、既に初期化されているというのはどうも腑に落ちない。結局、ローカルなスレッドプールを作ってmain()全体で使うようにした(実質グローバル)。

rayonについて調べていると、rayon::join()について扱っている記事を見つけた。これを読んで、(これを使ってマンデルブロ集合が描けるんじゃないか…?)と思っていた昔の記憶を思い出す。当時はRustの知識が無くて、コンパイルすら通せなかったけど、今なら書けそう。

戦略としては、領域を分割しながら各スレッドに投げていく感じ(rayon::join()を使っている)。

もし、領域の枠(端っこ?)のピクセルが全て集合に属していると判定されたら、その枠内のピクセルは全て集合に属するという処理をしている。Wikipediaで「マンデルブロ集合に穴は空いていない」的な記述を読んだ気がするけど、今見にいったら記述は無かった。どこで読んだのだろう。

初めて自分のコードでArcAtomicなんとかを使った。このピクセルは何回目の計算で発散判定されたかを記録するためのAtomicU32と、それを複数スレッドで共有するためのArc

実は、今の実装では一つのピクセルを複数のスレッドがいじる事は無いので、実際に競合する事は無いはず。だからといって普通のu32にしたらコンパイルが通らないのでAtomicU32を使っている。(unsafeな処理を書くほどでもないと思うので…)

これが実際に描画している光景。ふっしぎ〜〜

2022/01/15

13時ごろに起きる。

HHKB プログラミングコンテスト 2022(AtCoder Beginner Contest 235)に出る。D問題まで解くことができて、2206位だった。

パフォーマンスは1037で、レーティングは882から898になった。やったぜ

// ここに成績証のスクリーンショットを貼る

atcoder.jp

A問題

問題文の通りに実装

atcoder.jp

B問題

前から順番にシミュレーション。隣り合う要素を見る問題は、zip(a[:-1], a[1:])のようにするとインデックスの事を考えなくても良くて楽。

atcoder.jp

C問題

数毎のlistを持った連想配列を用意して、それぞれの出現インデックスを突っ込む。クエリに答える時は、listの長さを確認しながら出力する。

atcoder.jp

D問題

本日のやらかし。問題文を誤読して、30分くらい不毛な事をしてしまっていた。具体的には、後ろから取って、前に入れるを、前と後ろを入れ替えるに読み間違えていた。後から振り返って、どうしてこんな事に…という気持ちに。日本語が下手。

解法は、Nを始点に各操作の逆の操作をして、1に着いたら終了するメモ化もどきDFS。解説ではBFSをしていたけど、自分はDFS解法の方が好み。

競プロではきれいなコードはあまり要求されない(と思っている)けど、再帰関数のような複雑な処理を書く場合は、コードの読みやすさを意識して書く事で、分かりにくい凡ミス的なバグに気付くことができた。きれいなコードはバグを減らすのに重要だと感じた。(それでも誤読に気付かなかったのですが…)

atcoder.jp

昨日書いたマンデルブロ集合を描画するプログラムを眺める。画像を描画する際に、同じピクセルを何回も計算している事に気がついた。無駄な計算をするのは避けたいので、ピクセルの計算結果をキャッシュするようにしてみた(AtomicBool)。これで無駄な計算が無くなって、ちょっと高速化できた。

状態を保持したりするのにArcを使っていたけど、普通に参照を渡しても大丈夫だった。並行性むずかしい…

そんな感じでPCをいじっていると、突如津波警報の通知が飛んできて困惑。大きめの地震が発生した訳でも無く、そういやトンガの方で大きい噴火があったらしいけど、日本に影響は無いと発表されていたし…と思いつつTwitterを眺めていた。

しばらくするとTLに色々と情報が流れて来て、やっぱりトンガの噴火が関係しているらしい。NERVが”マグニチュードNaN”とツイートしていたけど、NaNってそういう…

実際、各所で30cm~1m程度の津波が観測されていて、これは大変だという気持ちに。

しばらくして気象庁の会見が始まったので、とりあえず眺めていた。発表によると、

  • これは所謂”津波”では無いけど、各所で潮位が上がっていて危険だったので津波警報のシステムを利用して発表した。
  • 通常の津波とは異なる点が多い。
    • 到達予想時刻より2時間早く到達した
    • 波の周期が短い
    • etc…
  • 予想時刻より早く到達したので、「なんか(潮位)上がっとるやんけ!」という感じで発表した

それで、原因は”トンガの噴火が絡んでいそうだけど、詳しくは不明”とのこと。不気味〜

そんな感じで、気象庁の会見を見たりしていたらオードリーのオールナイトニッポンを聴き逃した。ぐぬぬ

2022/01/16

15時ごろに起きる。

布団の中で目が覚めると、左腕の感覚が無い。「あれ〜?」と思い、左腕を確認しようと思ったら、顔の上に何かが乗っかっている事に気がついたので、右腕で触ってみると、それは左腕だった(???)。

左腕がもげたんじゃ無いかと一瞬思ったけど、つあんと繋がっていて一安心。「あれ〜?」と思い(二回目)右腕でいじってみるけど何も感じなくて、当然動かす事もできない。暫く布団でもぞもぞしていると、左腕がじーんとしてきて(痺れる時の逆再生みたいな感じ)、1分程度でいつも通りに戻った。なんだったの

寝ている間に津波警注意報は全部解除されていた。原因はやっぱり謎だとか。

久しぶりにインスタントうどんを作る。袋から出してお湯を入れるだけ、便利だ〜。

噴火の発生後から、トンガのインターネット通信がほぼ皆無になっているらしい。ひえ〜

https://radar.cloudflare.com/to

radikoでオードリーのオールナイトニッポンタイムシフトを聴く。

マンデルブロ集合を描画するやつをいじる。コード内のバラけている部分を統一したり(x, yの形で受け取るようにしたり)、収まりが悪いfor文をイテレーターの形に変えたりした。

イテレーターに変えたら、ベンチマークがちょっと良くなった。具体的にどう良くなったのか調べたいので、cargo-asmを使ってアセンブリを覗いてみたけど、よくわからず…

Rustのアトミック変数について調べる。メモリ順序という概念が出てきたけど、よくわからない…。難しそうだという事だけは分かる。とりあえず全部Acquire/Releaseにしておけば良い?