Write and Run

it's a simple way, but the only way.

極度に寝すぎた土日は無と区別がつかない

  • 金曜日の夜に飲んだ
    • 1時半くらいまで飲んでた
    • そのあと終電を逃した後輩と4時くらいまで Rust の話とかしてた
  • 土曜日は15時に起きた
  • 土曜日の夜に飲んだ
    • 就活で悩んでいる若者の人生相談に乗った
  • tokio::io::stdin() の poll_read がブロックする問題に気づけず4時間くらい溶かした
  • 日曜日は14時に起きた
  • トイレにいるときに UberEats が来て最悪な日になることを確信した

結果

USB接続で地デジ4チャンネル録画できるチューナーPX-Q1UDを買ったそして試した

最近は Rust と Java を交互に書くという脳トレをしています。KOBA789 です。

先日、知人から PLEX が新しいチューナー "PX-Q1UD" を出したという情報を聞き、気になって買ってみました。

価格は2万円弱ほどで、USB 接続で地デジを4チャンネル同時録画できるというシロモノです。 中身は PX-S1UD(こちらも持っている)相当を USB ハブ経由で4つぶら下げただけの構造で、ドライバも同じものが使えます。 というか、接続すると dmesg には PX-S1UD の名前が流れます。

以下、イケてる点とそうじゃない点のまとめです。

イケてる点

  • ドライバが最近の Linux カーネルに標準で入ってる
  • UHF の分配器や USB ハブを別途用意せずとも PX-S1UD を4本かき集めたのと同じ効果
  • USB 接続なのでマシンを選ばない = Raspberry Pi などでも使える!

イケてない点

  • バスパワーだと動かないときがあるっぽくて、同梱の AC アダプタが必要
  • B-CAS カードは付いてない
  • IC カードリーダーも付いてない

とまぁここまでで終わればよかったんですが、この PX-Q1UD をうまく動かすのは一筋縄ではいきませんでした。

PX-Q1UD SNR 安定しない事件

PX-Q1UD の実力を確かめるべく、Raspberry Pi 3 に繋いで recdvbchksig してみました。 すると、SNR の値が 100 になったり 0 になったりして全然安定しません。 一方、電波強度が足らないのかと思い PX-S1UD を引っ張り出してきて試してみると SNR は300(最大値っぽい)で安定します。

4分配しているので電波強度が足らなくなっているのかもしれない、と思ったのですが、そもそも SNR という値の単位や意味がよくわかりません。 PX-Q1UD の情報を提供してくれた友人に相談してみたところ、この SNR の値はぶっ壊れているとのことでした。

この SNR の値は DVB デバイスの frontend の fd に FE_READ_SNR を ioctl して取得している値のようでした。

recdvb 改造

しかし、V4L の DVB API のリファレンスによれば、前述の FE_READ_SNR は deprecated とのことです。

6.1.2.2. FE_READ_SNR — Linux Media Subsystem Documentation documentation

というわけで、recdvb の当該コードを書き換え、ついでなので取得できそうなプロパティを全部取得して表示する改造をしました。 calc_cn という関数をガッツリ改造します。 (_cn という名前なのに SNR = S/N を表示してんのはどういうワケなんですかねぇ)

gist.github.com

そして PX-Q1UD で動かしてみた結果がこうです。 (上記パッチより若干機能が少ないコードで実験したときのログなので、出力結果が異なります)

CNR: 8.000000 ERRBLK: 0 TOTALBLK: 0 SIG: -23.000000
CNR: 10.000000 ERRBLK: 8041 TOTALBLK: 8116 SIG: -22.000000
CNR: 10.000000 ERRBLK: 5184 TOTALBLK: 5312 SIG: -22.000000
CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -23.000000
CNR: 9.000000 ERRBLK: 2522 TOTALBLK: 2522 SIG: -22.000000
CNR: 10.000000 ERRBLK: 5012 TOTALBLK: 5135 SIG: -22.000000
CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -22.000000
CNR: 10.000000 ERRBLK: 2522 TOTALBLK: 2522 SIG: -22.000000
CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -23.000000
CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -22.000000
CNR: 10.000000 ERRBLK: 5173 TOTALBLK: 5178 SIG: -22.000000
CNR: 10.000000 ERRBLK: 5012 TOTALBLK: 5135 SIG: -22.000000
CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -22.000000
CNR: 10.000000 ERRBLK: 8033 TOTALBLK: 8109 SIG: -22.000000

(ERROR BLOCK だらけなんですが……)

比較のため、PX-S1UD でも測ってみました。

CNR: 0.000000 ERRBLK: N/A TOTALBLK: N/A SIG: -34.000000
CNR: 30.000000 ERRBLK: 2354 TOTALBLK: 2522 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 0 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 15759 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 26383 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 39960 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 47631 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 55599 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 63567 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 84816 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 98096 SIG: -34.000000
CNR: 30.000000 ERRBLK: 0 TOTALBLK: 98096 SIG: -34.000000

「あれ、PX-Q1UD のほうが電波強度(SIG)が強い……」

f:id:koba789:20180315213119p:plain

(ここで X-File のテーマソングが流れる)

さっきまで4分配してるから電波強度落ちてんじゃないのかなー、などと思っていたのですが計測結果は 真逆 でした。 どちらも同じチップを積んでいるので、機種ごとの差、というわけでもなさそうです。

となれば疑うべきはただ一つで、

PX-Q1UD は分配で減る分を補填するためにブースターを内蔵しているのでは

です。

そして

信号がサチってて C/N が悪化しているのでは

という予想が立てられました。

レッツ分解

最近のハードウェアは実装密度が高すぎて、開けても肉眼では何の情報も得られないことがほとんどなんですが、せっかく手元に物体があるので、蓋を開けましょう。

f:id:koba789:20180315002835j:plain

f:id:koba789:20180315003413j:plain

2枚目、シールドを外すとチューナーと思しき石が4つ出てきました。そして右側には USB ハブっぽい石。マジで素朴。

で肝心のアンテナ線は左から来てアンプっぽい石を通ったあと、分配器っぽい石に突っ込まれています。

しかしゲインの調整をできそうな半固定抵抗などは見つからず、そっと蓋を閉じました(やっぱり何もわからなかったじゃねーか)。

信号がサチっているなら

ということで無意味に分解しただけとなりましたが、信号がサチっているのであれば対策は簡単で、信号を減衰させればいいのです。

世の中には電波の信号を減衰させるためのパーツもあって、アッテネータといいます。がしかし、私の手元にはありませんでした。 ので、最終手段「半刺し」です。

半刺し

アンテナ線を半刺しにすると、信号が減衰します(あたりまえ)。

お金もかからず、すぐに実践できるテクニックです。

f:id:koba789:20180315001303j:plain

すると……

CNR: 10.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 0 (counter) SIG: -22.000000 dBm
CNR: 0.000000 dBm ERRBLK: N/A TOTALBLK: N/A SIG: -23.000000 dBm
CNR: 0.000000 dBm ERRBLK: N/A TOTALBLK: N/A SIG: -23.000000 dBm
CNR: 10.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 0 (counter) SIG: -22.000000 dBm
CNR: 0.000000 dBm ERRBLK: N/A TOTALBLK: N/A SIG: -23.000000 dBm
CNR: 9.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 0 (counter) SIG: -22.000000 dBm
CNR: 23.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 2479 (counter) SIG: -40.000000 dBm
CNR: 25.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 10447 (counter) SIG: -45.000000 dBm
CNR: 25.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 21071 (counter) SIG: -47.000000 dBm
CNR: 28.000000 dBm ERRBLK: 0 (counter) TOTALBLK: 37007 (counter) SIG: -47.000000 dBm

(CNR の単位は本当は dB です)

SIG の値が -47 まで下がり、と同時に CNR が 25dB まで改善、ERROR BLOCK も0になりました。めでたい!!!

結論

というわけで、PX-Q1UD はいい製品ですが、電波強度の強い環境で使うときには信号がサチってしまうことがあります。 アンテナ線半刺しなどのテクによって乗り切りましょう。

乗り切る自信がない人にはアッテネータが便利です。

kubernetesと戯れる中で出会った概念たち

とにかく kubernetes は独特の概念が多い。この辺の土地勘を掴まないとやっていけない。

正直言って個人の日記レベル。詳しいことは公式を見てくれ。それではいきます。

Pod

機能を構成する最小単位っぽい。1個以上のコンテナで構成される。sidecar コンテナまでまとめたやつが Pod っぽい。わからん。

Replica Set

上記 Pod を複製するやつっぽい。わからん。

Deployment

Replica Set を世代管理したりできるやつ。カナリアリリースとかが主な機能っぽい。わからん。

Service

機能を露出させる単位っぽい。わからん。

Ingres

ロードバランサっぽい。わからん。

Persistent Volume

ストレージの親玉。サーバーの管理者がガッとプロビジョニングしておくようなやつで、カジュアルに増減するようなものではない。後述の PVC を元に容量を払い出してくれるやつっぽい。わからん。 具体的にはクラウドで言うところの AWS EBS とか GCE PersistentDisk とかが相当するっぽい。

Persistent Volume Claim

PVC と書かれることが多い気がする。上記 Persistent Volume に割り当てを申請するやつ。1GB くれみたいなこと書くとスッと降ってくるっぽい。わからん。

StatefulSet

Deployment よりもステートフルな物体を管理することに長けてるっぽい。まったくわからん。

Custom Resource

上記に書いてきた物体はそれぞれ Resource と呼ばれるものの一種らしい。で、その Resource は追加で定義することができて、それが Custom Resource っぽい。 独自の機能を kubernetes に追加したりできるんですかねぇ。わからん。

Operator

これは kubernetes 公式の概念っつーか、サードパーティー(CoreOS が提唱した?)の概念っぽい。

coreos.com

マネージドサービスっぽいものを Custom Resource を用いて実現する物体のことをこう呼ぶらしい。 Custom Resource として何らかのミドルウェアの Operator を追加しておくと、そのミドルウェアを使うときには kind: そのなんらかのミドルウェア みたいな感じで YAML に書くだけで用意できるっぽい。 わからん。

RustをEmscriptenなしでwasmにコンパイルしてNode.jsから呼び出す

std: Add a new wasm32-unknown-unknown target by alexcrichton · Pull Request #45905 · rust-lang/rust · GitHub

Rust の nightly で wasm32-unknown-unknown という target が入ったので、Emscripten ナシでも wasm を吐けるようになったということで。

やった。

github.com

普通に serde とか使えて便利。

文字列を渡すときには Rust 側の関数で alloc してヒープのそのポインタへ JS から書いてやる必要がある。で、関数にはそのポインタを渡す。 受け取るときはポインタが返ってくるのでヒープを読みに行く必要がある。while (mem[ptr] != 0) みたいなことになってるけど、これもっといい方法無いんですかね。

あと、dealloc は忘れずに。

fat pointer を返したらいいんじゃね? と思ったけど、128bit をどうやって渡せばいいんだろうな wasm32 だから fat pointer は 64bit か?

ISUCON7「学生気分」

これは決勝出場決定チームなどと飲んだあとに酔っ払って書いている。明日は土曜日。

 

細かいことは http://osyoyu.hatenablog.com/entry/2017/10/23/014843 に書いてあると思う。この記事を読めば俺の記事は用なし。

 

8万点くらいしか取れなかったけど、かつてないチームワークを発揮し、それぞれのパフォーマンスを生かしきったいい試合だったと思うので、酔っ払いながらに書いておく。よかった。

 

git 禁止

今回で出場は3度目だが、過去二回の出場で学んだことがある。我々には運用をする奴がいない。再起動には耐えられないし、本番で ruby を動かす方法は知らない。学生はあくまでオモチャしか知らないのだ。そのため、我々にはチームワークがない。運用する奴がいないので全員がバラバラにコードを書き始める。最悪だ。

 

そこで今回、俺はある提案をした。それが git 禁止だ。

git を禁止し、あくまで本番サーバー上での編集しか許さないというルールを敷いた。このことで、コードを書く人間は一人となり、ロックを取るためにコミュニケーションが発生した。

コードを書けない人間は計測するとか便利スクリプトを揃えるとかするしかなくなる。これにより自然と分担が発生した。ちなみに俺は mysql に関する知識がミジンコ並だったのでミドリムシ程度の知識がありそうな @osyoyu に投げた。結果的に彼は MySQL 8 をインストールし損ねて環境を破壊するも、なんとか my.cnf を保守し続けてくれたので、複数の細胞からなる知的生命体であったということになった。

 

mamiya.sh

そうだね。

 

これも @osyoyu 作。3台あったマシンのうち、編集を許されていた1台目のサーバーの環境を2台目,3台目に rsync するための物体。

 

憧れの @sora_h パイセンの代表作(?)にあやかった名前をつけている。実際便利。

 

Redis 導入

よくわからないうちに redis が投入されていた。@everysick の貢献。

速くなったらしいが比較をしていないのでわからない。速そう。

 

キャッシュヒット

たぶんこれが主な敗因。

/icons/ 以下を3台それぞれのファイルシステムから nginx で配るようにしてしまった。ベンチマーカーはキャッシュ関連のヘッダを読んでくれるっぽいんだけど、3台からそれぞれやるとキャッシュヒット率が1/3。Last-Modified がね〜〜。

この辺は精進が足らない。ちなみに我々は計画的なので今回も素振りはありませんでした。精進あるのみ。

 

req_limit

/fetch に sleep を見つけた我々は、一度それを外すも、スコアにならないエンドポイントを高速化してもしゃーないことに気づいた。

しかし、ruby のスレッドを sleep で占有したくないと思った私は nginx で req_limit を差し込み、適当にゆっくりとレスポンスを返すこととした。

まぁまぁ効いた。俺作。貢献あってよかった。

 

〜〜

 

あとなんかあった。

パソコン難しいけど、チームワークは大切。git はダメ