Macの無線LAN通信が途切れることがあるので「ワイヤレス診断」で監視してみた

同じ無線LANに繋いでいるMaciPhoneのうち、Macだけが通信できなくなることがあるので、その時何が起きているのかをmacOS標準アプリのワイヤレス診断で観てみる。

f:id:chryfopp:20210104165555p:plain

「スキャン」ウインドウ

まずは帯域の混み具合をスキャンウインドウで確認。

f:id:chryfopp:20210102223709p:plain

2.4Ghz帯、5GHz帯合わせて25件確認できる。(うち4件は自室のアクセスポイント)

Wi-fiルーター3種を繋ぎ変えながら「パフォーマンス」ウィンドウを眺める

Aterm WG1200HP3

光コラボのプロバイダーからレンタルしているルーター
このルーターの5GHz帯のチャンネルは、クワッドチャネル(80MHzチャネルボンディング)機能とオートチャネルセレクト機能を有効にしていると36が選ばれる。
オートチャネルセレクト機能を無効にすると「W52」「W53」「W56」の3つから選べるようになり、W52を指定すると36が、W53を指定すると52が、W56を指定すると100か116が使われる。
試しにW56を選んでみたところ、少なくとも1日1回程度の頻度でチャンネルの切り替わり(100↔︎116)が発生していた。実際、使っているときにも急に一分程度ネットワークに接続できなくなる現象に遭遇したので、そこそこの頻度でDFSが発生していそう。
W53の方は、ちょっと使ってみた感じではDFSで使えなくなるようなことはなさそうだったので、とりあえずこっちのチャンネルを使ってみる。

f:id:chryfopp:20210101174606p:plain

接続直後は2ストリームのデータレート(866.7Mbps)が記録される。

しかしこれがたまに40Mpbsになったりして

f:id:chryfopp:20210101181610p:plain

こうなるとネットの回線速度テストの数値も10Mbpsくらいになる。

f:id:chryfopp:20210101190214p:plain

データレートは6Mpbsとかになることもあり

f:id:chryfopp:20210101190809p:plain

ここまでくるとルーターpingすら通らなくなる。

% ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3

一瞬別のアクセスポイントに繋いでから繋ぎ直すと、一瞬復活しそうに見えるが、すぐに再接続前のデータレートに戻る。

f:id:chryfopp:20210101193542p:plain

この状態からの回復には、MacWi-fiをon/offするのが手っ取り早い。
Macが通信できなくなっている時でも、iPhoneは問題なく通信できているので、ルーター側をどうこうする必要はない。

AirMac Time Capsule 802.11ac

光コラボ回線を引くまで使っていた無線LANアクセスポイント。
Time Capsuleルーターとしては光コラボ回線のv6プラスには対応していないらしいので、ルーターAtermのまま、Time Capsuleはブリッジモードで繋いで使用する。
チャンネルは手動では「36」「40」「44」「48」の4つからしか選べない。
とりあえず自動選択にしてみたところ、初めは100が選ばれたのだが、いつの間にかW52のチャンネルに切り替わっていた。DFSが発生するとW52に移るのかもしれない。

f:id:chryfopp:20210101191618p:plain

最大データレートは1300Mbps(3ストリーム)、低くても大体866Mbps以上と、パフォーマンスウインドウの表示上はかなり安定する。
……のだが、こいつはこいつで1300Mbpsのデータレート表示を保ったままpingが通らなくなることがあり、こうなったらこれまたMacWi-fiをon/offすることになる。

Archer A2600 Pro

AtermやAirStationといった自分が使ったことがあるルーターではなくてv6プラスに対応しているルーターを試したくてこれを選択。
このルーターではチャンネルは36から140まで指定できる。試しにAtermと同様に52を指定してしばらく使っていたら、いつの間にか設定値は52のままで、実際のチャンネルは40になっていた。結局W53でもDFSが発生して、W52に移ったのかもしれない。

f:id:chryfopp:20210105000104p:plain

MacBook Pro (16-inch, 2019)と繋いだ時の最大データレートはTime Capsuleと同じ1300Mbps。4ストリームの1733Mbpsには(おそらくMac側のアンテナ数が足りなくて)ならない。
全体的な挙動はTime Capsuleと似ていて、これも(主にスリープ復帰後などに)1300Mbpsのデータレート表示を保ったままpingが通らなくなることがある。

f:id:chryfopp:20210104235823p:plain

所感

結局Aterm以外では、通信の不調時にもワイヤレス診断のパフォーマンスウインドウではこれといった変調の傾向は見つけられなかった。
どのルーターに繋いでいても、調子が悪くなったらMacWi-fiをon/offすればそれなりに調子は戻るが、本調子に戻したいならばMacを再起動するしかない。

Macpingが通らなくなる現象が発生しているときに、同じルーターに接続しているiPhoneで実行したネット回線速度テスト結果:

f:id:chryfopp:20210106135940p:plain

MacWi-fiをon/offした後のネット回線速度テスト結果:

f:id:chryfopp:20210106135718p:plain

Macを再起動した後のネット回線速度テスト結果:

f:id:chryfopp:20210106140026p:plain

調子悪い時にデータレートが下がるのが見て取れるという点においては、Atermが一番信用できるかもしれない。

ちなみにワイヤレス診断には「診断」という機能があるが、これを使うと

f:id:chryfopp:20210105002140p:plain

という情報が提供される。特に役には立たない。

ソースコードの読者

science.srad.jp

私は、プログラミングは「誰に伝えるか」を意識しながら書かなければならない点において「作文」に近いと思う。

ソースコードの読者は

  1. 言語処理系
  2. 人間

の2つ。

最低1つの処理系で読めるように書くのは当然(さもなくばプログラムは動かない)として、それ以外のどの処理系で読めるように書くのか、どのような人間に読めるように書くのか、そのためにどれだけの手間を掛けるか。よほど特定の処理系に特化したアルゴリズマーでない限り、プログラマーにはこのあたりのバランス感覚が必要となる。

「要件」のあるべき姿とは

ものづくりにおいて「要件」のあるべき姿とは

「これをすべて達成すれば関係者皆がハッピーになるだろうと、関係者皆で合意して一蓮托生進めていくことにした仮説」

として捉えられることである。

あくまで仮説なので、真に正しいことの証明は実際にものを市場に出すことでしか成し得ないが、各種マーティング技法などによって確度を高めることはできる。

ものづくりを進め、形が見えてくると、以前立てたものよりも優れた仮説が提唱されることだろう。そのような時に新しい仮説に乗り換えられるようにしておく仕組みを「変更管理」という。変更管理をないがしろにできるのは、よほど関係者全員が最初の仮説に絶対の自信を持っている場合に限られる。

strcpyの未定義動作例

コード

#include <iostream>
#include <string.h>

int main()
{
    char buffer[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWX";
    strcpy(buffer, buffer+8);
    std::cout << buffer << std::endl;
    return 0;
}

実行結果

処理系 結果
Wandbox
clang 9.0.0
89ABCDEFGHIJKLMNOPQRSTUVWX
macOS 10.15.1
Apple clang version 11.0.0
89ABCDEFGHIRSTUVOPQRSTUVWX

原理

https://opensource.apple.com/source/Libc/Libc-1244.50.9/x86_64/string/strcpy.s.auto.html

つまり

処理 buffer[35]
初期状態 0123456789ABCDEFGHIJKLMNOPQRSTUVWX\0
buffer+8から16バイトコピーする 89ABCDEFGHIJKLMNGHIJKLMNOPQRSTUVWX\0
16バイト境界に沿って16バイトコピーする 89ABCDEFGHIJKLMNOPQRSTUVOPQRSTUVWX\0
末尾16バイトをコピーする 89ABCDEFGHIRSTUVOPQRSTUVWX\0RSTUVWX\0

ImageMagickのrotateはバージョンによってoFFsが付いたり付かなかったりする

試したのはCentOS 6と7の標準リポジトリに入っているImageMagick

CentOS 6

$ cat /etc/redhat-release
CentOS release 6.10 (Final)
$ convert --version
Version: ImageMagick 6.7.2-7 2017-03-22 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP
$ convert logo: -rotate -45 norepaged6.png
$ identify norepaged6.png
norepaged6.png PNG 792x792 792x792+0+0 8-bit DirectClass 147KB 0.000u 0:00.000

CentOS 6のImageMagick 6.7.2-7のrotateではoFFsチャンクは埋め込まれない。

CentOS 7

$ cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
$ convert --version
Version: ImageMagick 6.7.8-9 2019-08-08 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
$ convert logo: -rotate -45 norepaged7.png
$ identify norepaged7.png
norepaged7.png PNG 794x794 794x794-77-157 8-bit DirectClass 119KB 0.000u 0:00.000

CentOS 7のImageMagick 6.7.8-9でrotateすると、「640x480の画像が左右77ピクセルずつ、上下157ピクセルずつ拡張された」という意味合いでかoFFsチャンクが埋め込まれる。

oFFsが埋め込まれていようといまいと単体で見る分には違いは出ないが、画像編集では影響が出てくる。

例えば先ほどrotateさせたoFFs有りの画像をImageMagickでcropすると

$ convert norepaged7.png -crop 200x200+100+100 norepaged7_crop.png
$ identify norepaged7_crop.png
norepaged7_crop.png PNG 200x200 794x794+100+100 8-bit DirectClass 21.5KB 0.000u 0:00.000

f:id:chryfopp:20191028224737p:plain
norepaged7_crop.png

こうなるが、rotate後にrepageしてoFFsを取り除いてからcropすると

$ convert logo: -rotate -45 +repage repaged7.png
$ identify repaged7.png
repaged7.png PNG 794x794 794x794+0+0 8-bit DirectClass 119KB 0.000u 0:00.000
$ convert repaged7.png -crop 200x200+100+100 repaged7_crop.png
$ identify repaged7_crop.png
repaged7_crop.png PNG 200x200 794x794+100+100 8-bit DirectClass 6.24KB 0.000u 0:00.000

f:id:chryfopp:20191028224702p:plain
repaged7_crop.png

こうなる。

プログラマーと要求分析と

内なる“怒り”が新生FFXIVを作った——不定期連載「原田が斬る!」,第6回は「ファイナルファンタジーXIV」吉田直樹氏に聞く,MMORPGの過去と未来

全文面白いのだけれど、とりわけ2ページ目に書かれている、プランナーとプログラマーの関係が興味深い。

原田氏: 「じゃあビカッ! ってなる,今業界で話題の粉みたいなやつ……なんでしたっけ?」「パーティクル?」「そのパーティクルが毎回同じのが出るのでつまんないんです」「じゃあどうしたいの?」「なんか毎回違うのが良いです」「それはランダムって意味?」「ランダムというか,すごく強いときはこんな風にボン! こっちに殴ったときはあっちにボン! って」「うーん,原田がやりたいことは分かった。じゃあ待ってて」って。で,次の日見たら,殴った方向や強さに合わせてにパーティクルが飛ぶようになっていた。

このプログラマーは、とにかく早く(現在のプロジェクトにおいて)意思確認ができるようになることを優先している。

吉田氏: ウチは「ビカッ! って感じです」なんて言ったら,「お前な,今日び,すすきのを歩いてるニーチャンだってビカッて言うぞ?」ってスゴまれましたよ。だから描けない絵で一生懸命パーティクルの話をしようとするんだけど,当時はそんな言葉すら知らなくて,また冷たい目で見られるっていう。 その代わり,分からないから教えてくださいって頭を下げたら,1から10まで全部説明してくれるんです。パラメータをいじるだけで指向性が変えられるとか,エントリーしてるエフェクトの粒のタイプをいくつも作ることによって,同じエンジンでも違った表現ができることとか。かつ,それを踏まえて発注したら,「お前がやりたいのはこうだろ?」って,発注以上のものがあがってくるんです。

このプログラマーは、プランナーが意思表現を文書で行えるようになることを(プランナーが自分のやりたいことを自分の力で正確に伝えられるようになるスキルの習得を)優先している。

両者のアプローチは異なりつつ、しかし最終的にはどちらのプログラマーもプランナーの初期のざっくりとした発言から、プランナーが本当に実現したかったことを引き出すという、要求アナリストとしての結果を出している。 往々にして、はたから見て優秀なプログラマーとは、要求分析が得意なプログラマーのことである。

原田氏: だから,僕はディレクターやプロデューサーになった当初,教育係としては苦労したんです。 あげく「プログラマーがもっと教えてあげてよ」とか言って,「えー! マジっすか?」って言われちゃう状態でした

要求分析が得意なプログラマーに甘やかされた(プログラマーに要求アナリストの役割を兼任されていた)経験があると、プログラマーと要求分析の役割は可分であるということに気づきにくいかもしれない。 好きで要求分析をするプログラマーはいるし、実際それは効率が良いのだが、その役割を明示的に与えられていない限り、プログラマーには要求分析をする義務はない。 「顧客が本当に必要だったもの」という有名な図があるが、この図は「無駄をそぎ落とした純粋なプログラマーの役割(期待すべき成果)」を正しく表していると思う。