読者です 読者をやめる 読者になる 読者になる

Write and Run

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

Rustのstd::io::copyとEchoサーバー

気が向いたので Rust でも書いてみるかという感じになって書いてるんですが、TCP Echo サーバーを書くだけで躓いたのでメモ。

fn main() {
    use std::io::prelude::*;
    use std::net::{TcpListener, TcpStream};
    use std::thread;

    let listener = TcpListener::bind("127.0.0.1:8124").unwrap();

    fn handle_client(mut stream: TcpStream) {
        std::io::copy(&mut stream.try_clone().unwrap(), &mut stream);
    }

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                thread::spawn(move|| {
                    // connection succeeded
                    handle_client(stream);
                });
            }
            Err(e) => { /* connection failed */ }
        }
    }

    // close the socket server
    drop(listener);
}

handle_client 内、std::io::copy の引数に std::io::copy(&mut stream, &mut stream) とやりたくなるが、ownership が第1引数に渡ってしまうので第2引数が不正とみなされコンパイルエラーになる。それを避けるために try_clone() しているが、内部的にはファイルディスクリプタの複製をやっているようで、ちょっと無駄っぽい気がする。

std::io::copy を使わずにこうすれば平気。

    fn handle_client(mut stream: TcpStream) {
        let mut buf = [0; 128];
        let mut written = 0;
        loop {
            let len = match stream.read(&mut buf) {
                Ok(0) => break,
                Ok(len) => len,
                Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
                Err(e) => break,
            };
            stream.write_all(&buf[..len]);
            written += len as u64;
        }
    }

とはいえ、せっかくのユーティリティ関数使いたいよなぁ。

Rust に詳しい人、ベストプラクティスを教えてください。

Raspberry Pi 2 Model Bが届いたのでB+と比較したりベンチマークしたりしてみた

来月の生活費がありません。KOBA789 です。 来月の生活費がないのに Raspberry Pi 2 が出たと聞いて速攻でポチりました。10人位でまとめて購入したので一気に口座から5万くらい飛んでいきました。未払い各位は僕に生活費を払いに来てください。よろしくお願いします。

さて、その Raspberry Pi 2 Model B が早速届いたのでベンチとかしてみよう、というのが今回の主題です。では張り切っていきましょう。

スペックで見る Raspberry Pi 2 Model B

公式サイトの解説ページ曰く、

A 900MHz quad-core ARM Cortex-A7 CPU (~6x performance)
1GB LPDDR2 SDRAM (2x memory)
Complete compatibility with Raspberry Pi 1

とのこと。CPU が速くなってたり、RAM が倍増してたりします。RAM が 1GB あると VRAM を増やせるので嬉しいですね。

ちなみに Model B+ と比較するとこんな感じ。

Raspberry Pi Model B+ Raspberry Pi 2 Model B
SoC BCM2835 BCM2836
CPU ARM1176JZ-F ARM Cortex-A7
GPU Dual Core VideoCore IV Dual Core VideoCore IV
RAM 512MB 1GB

引用元: High Definition 1080p Embedded Multimedia Applications Processor - BCM2835 | Broadcom, Raspberry Pi 2 on sale now at $35 | Raspberry Pi

写真で見る Raspberry Pi 2 Model B

左が B+ 右が 2 B。ロゴがちょっと小さくなってます。また、B+ の SoC には SUMSUNG のロゴが印字されていますが、2 B は Broadcom のロゴですね。

f:id:koba789:20150205173024j:plain

向きを変えてもう1枚。左が B+ 右が 2 B。

f:id:koba789:20150205173102j:plain

特徴的な裏側。左が B+ 右が 2 B。2 B は裏に ELPIDA のメモリセルがあります。B+ のときは SoC 内蔵だったから容量が小さかったのでしょうか。

f:id:koba789:20150205173135j:plain

追記: こういうことっぽい。賢くなった。

起動

とりあえず手元の microSD に Raspbian を焼いて起動してみました。クアッドコアの証として、2 B はコンソールの左上にロゴが4つ表示されます。

f:id:koba789:20150205184420j:plain

起動速度

参考までに dmesg のログを貼っておくとこんな感じです。

B+

[   32.236583] Adding 102396k swap on /var/swap.  Priority:-1 extents:2 across:2162644k SSFS

2 B

[   15.395821] Adding 102396k swap on /var/swap.  Priority:-1 extents:2 across:2162644k SSFS

速いっぽいです。

/proc/cpuinfo

クアッドコアと聞いて、まずやってみたくなるのはこれですよね?

pi@raspberrypi ~ $ cat /proc/cpuinfo
processor   : 0
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 1
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 2
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 3
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

Hardware    : BCM2709
Revision    : a01041

うひょー! マジで4コアある!!!! しかし、Hardware: BCM2709 というのが気になりますね……。

/opt/vc/src/hello_pi/hello_encode

CPU はたぶん速くなってるだろうという予想がつくので、どちらかというと気になるのはOpenMAX のほうではないかと思います。というわけで動画のエンコードの実験をしてみます。

まずは B+ から。

pi@raspberrypi /opt/vc/src/hello_pi/hello_encode $ time ./hello_encode.bin /dev/null > /dev/null

real    0m4.781s
user    0m3.600s
sys 0m0.450s

次に 2 B。

pi@raspberrypi /opt/vc/src/hello_pi/hello_encode $ time ./hello_encode.bin /dev/null > /dev/null

real    0m2.595s
user    0m1.870s
sys 0m0.130s

2倍とまでは行きませんが有意な差が出ています。この速度差が CPU の高速化によるものなのか、あるいは CPU 同様に GPUクロックアップしているのかという点については今後更に詳しく調べる必要がありそうです。

まとめ

2 B 速いです。まぁこの小さいボードがそんなに速くなってなにが嬉しいんだという気もしますが、$35 でこの性能ですから非常に遊びやすくなったと言えると思います。なにより RAM 1GB が本当に嬉しいですね。

さてなんで私がこれほどまでに(今更) Raspberry Pi で興奮しているのかというと、Raspberry Pi 向けの HDMI キャプチャユニットを開発中だからです。Raspberry Pi で HDMI がキャプチャできれば LT のスライドにオーバーレイでコメント流すデバイスを作ったり、LiveShell のような使い方をしたりということができるようになるんではないかと考えています。

それではまた。

これはcoins Advent Calendar 25日目の記事です

あけましておめでとうございます。今年もよろしくお願いします。

今日がクリスマス、というのが一般的な見識かと思いますが、割と一部ではそうではないみたいなこともあって、というか今日はもうすでに年明けてるかもしれなくて、君の枕元にあったクリスマスプレゼント(ちくわ大明神)の代金はこっそりお年玉から天引きされてた、なんてこともありえるわけです。あそこにベンツが止まっていますが、君のお年玉では買えません。まぁ牧瀬紅莉栖に言わせれば未来の可能性は無限らしいので何言っても嘘にはならないと思いますし、せっかくなのでどんどん法螺吹いていこうかと思います。(ここで法螺貝の音が聞こえるはず。聞こえない人は今すぐ病院に行ってください)

さて、なぜクリスマスの日付について言及したかというと、合理的なクリスマスというのは12月の25日ではないからであります。クリスマスにはケーキと七面鳥を食べたり、カップルであればなんかいい感じの場所に出かけたりするのでしょうが、まともに考えて12月25日にクリスマスを祝う人間(あるいは便乗して盛り上がるだけの人間)が一気にそれらの行動をすればそりゃ世界規模の DDoS なわけで、ケーキも七面鳥も高騰するし、ラブホも満室になるわけです。そこで勘のいい人間はクリスマスを12月26日以降に祝うということを思いつくわけです。俺は勘がいいので気づいたんですよ。どうだ参ったか。三回回ってワンと言え。

そもそもですね、サンタクロースだって1日で全世界を廻らなきゃいけなくて大変なんですよ。キリストが生まれてから2000年ほど経つっぽいですが、2000年もの間サンタクロースはキリストの誕生日前夜の1晩で世界を回るために多額の資金を投入して技術開発を行ってきたわけですからね(いや知らんけど)。ほんと頭が上がりません。でもですね、人類は2000年の時間をかけて賢くなったわけですよ。ピークタイムをずらせばサンタクロースの苦労も減るという偉大な発見を、今日、俺が、この記事で、みなさんにお伝えするわけです。それこそ1年かけて世界を回ればね、もうね、365倍楽なわけですから。365倍楽になるというのは0.5単位取ったら卒業要件を満たせちゃうっていうレベルの革命ですよ、この発見がいかに偉大であるかわかりますか。

そういうことなんでサンタクロースは1日遅れてやってきます。今朝起きた時にプレゼントが届いてなかったと慌てた読者の皆さんも実際ご安心です。プレゼントがなかったのは今年良い子にしてなかったのがバレたからだと落ち込む必要はもうないわけです。まぁみなさんがいい子にしてなかったことはどーせサンタクロースにモロバレですので、プレゼントの内容に関しては期待できないかと思いますが。

ともあれ、coins にもクリスマスプレゼントがありますように。

Arietta G25 で遊ぶ

なんか久しぶりにブログを書く気がします。KOBA789 です。

Arietta G25*1 というボードを @ 氏から買いました。これがどんなものかというと、

  • 小さくて
  • 安くて
  • 簡単な
  • ARM9@400MHz

というものです。400MHz ですが Debian GNU/Linux が動くし、何より小さい(フリスクに入る)し、Raspberry Pi はちょっとデカくてイケてないよねー、みたいなときにいい感じです。あと、「猫も杓子も Raspberry Pi 使いやがって癪に触るんじゃ」みたいな人にもおすすめです。さらにいうと ADC ついてます(Raspberry Pi にはない)。

興味があれば @ 氏に声をかけると(まだ在庫があれば)売ってくれるんじゃないかと思います。

今回はそんな Arietta G25 で遊んでみたので、遊び方のまとめを書くことにしました。なお、公式のチュートリアルTutorialsです。

イメージ焼き

なにはともあれ microSD を焼きます。公式が配ってるイメージがいいと思います。以下からダウンロードできます。arietta_no_wifi.img.zip ってやつがそれです。

Download microSD images

まぁなんとなく dd とかで焼いてそういう感じにします。

sudo dd if=arietta.img of=/dev/rdisk2 bs=1m

起動

いい感じの焼き色になったら Arietta G25 に入れて、microUSB ケーブルで母艦とつなげます。母艦はできれば Linux 機がいいと思います(後述)。

さてこの Arietta G25、HDMI 出力もなければ USB ポート(ピンを引き出せば3つくらいあるけど)もありませんので、Raspberry Pi のように画面とキーボードを繋げて、みたいなことはできません。どうするかっつーと、母艦が Arietta G25 を USB 接続の Ethernet ポートとして認識するので、そこへ SSH する、という方法をとります。母艦が Linux のほうがいいというのは、Arietta G25 をインターネッツの大海原に導いてやるために母艦で IP フォワーディングやら IP マスカレードやらする必要があるからです。

以下、Linux でやるのが一番楽っぽいので母艦を Linux として説明します。その他のプラットフォームに関しては公式のページ(Getting started with Arietta)を読んでください。

Arietta G25 を接続すると、usb0 というデバイスが見えます(systemd とかで書き換えられている人はわからないので読み替えてください)。こいつが Arietta G25 の正体なので、IP アドレスを与えて link-up してやります。公式のイメージでは Arietta G25 の IP アドレスは 192.168.10.10/24 で決め打ちっぽいです。で、デフォゲは 192.168.10.20/24 ということになってます。なので、

$ sudo ip addr change dev usb0 192.168.10.20/24
$ sudo ip link usb0 set up

とします。これでとりあえず 192.168.10.10SSH できるようになりました。しかし、このままでは母艦と通信できるだけでパケットが外に出られないので、いい感じにフォワーディングとか NAT とかしてやります。eth0 は読み替えてください。

$ sudo sysctl net.ipv4.ip_forward=1
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

これで Arietta G25 もインターネッツにつながるようになりました(パチパチ)。

さっそく SSH してみます。デフォルトパスワードは acmesystems です。

koba789@ubuntu:~$ ssh root@192.168.10.10
root@192.168.10.10's password:
Linux arietta 3.16.1+ #3 Sat Aug 30 14:39:44 CEST 2014 armv5tejl

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Jan  1 01:30:24 2007 from 192.168.10.20
root@arietta:~# uname -a
Linux arietta 3.16.1+ #3 Sat Aug 30 14:39:44 CEST 2014 armv5tejl GNU/Linux
root@arietta:~#

よさそうです。ちなみに時計がおもいっきりズレてるので、ntp とかでいい感じにしてあげたほうがいいと思います。

まとめ

だるくなったので GPIO とかは次回に回そうかと思います。では。

AngularJSは今すぐ生まれ変わるか死ね

mizchi 氏のエントリを踏まえて。

Angularが嫌い - mizchi's blog

何をやるにもググって解決しなければならないぐらいには一貫性がない

マジでこれ。設定が多すぎる。特に directive 定義。どうやら Web Components の流儀に沿うようになっていて、将来的には Web Components に乗っける、ということらしいが、そもそもの Web Components の仕様が汚いし、救いようがない。

参考: AngularJS: Developer Guide: Directive

制御構造と要素を分離してねぇせいで replace とかいうオプションが生えてるし、tranclude との組み合わせでより複雑なことになるし、isolated scope な directive は併用できないとか、ng-repeat で作られた scope の下に他の directive の scope が入るように優先度とかいう暗黙的な値があったり、マジでクソ。その優先度はコードのどこに見えるんですか!!! ドキュメントと本体の実装ですかそうですか!!! ライブラリの知識がないとコードの意味がわからないから雇用が守られていいですね!!! 100 飛びで優先度を振ってあるから横入りしやすくて便利だと思います!!! N88 BASIC の行番号じゃねぇんだぞ死ね!!!

AngularJS の不健全さを知るためには、とりあえず restrict オプションを見とけばいいと思う。directive を attribute でマッチするか、element でマッチするか、class name でマッチするか、というオプションなんだが、それを "A" "E" "C" という文字列の「連結」で表現する。つまり、attribute と element なら "AE" という文字列を指定することになる。なんだそれ。マトモな脳ミソなら { element: true, attribute: true } にするよな。getUserMedia だってだいぶ前に直ったんだぜ?

とにかく、AngularJS の設計が気に食わない。なんでどこもかしこもアドホックなルールだらけなんだ。犯人がわかったと思ったら後出しでアリバイが出てくる推理小説かよこれは。

AngularJS は今すぐ生まれ変わるか死ね。あと Object.observe を AngularJS のためだけに Chrome に先行実装してゴリ押しするのやめろ。