Write and Run

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

LINEインターンに参加した

40万円

f:id:koba789:20160904022502j:plain

LINE Payのチームでなんかの実験環境を作ったりしました。

f:id:koba789:20160902132637j:plain

例えば、これは最終日の昼に食った肉です。

f:id:koba789:20160807073851j:plain

たまたま倒壊していなかったときの建物です。

ほかにもなにかを作ったりしました。はやくリリースされるといいですね。

f:id:koba789:20160807034851j:plain

つくばから東京までは自転車で行って、五反田のベッドで寝てました。

f:id:koba789:20160825100314j:plain

これは見えるやつです。

f:id:koba789:20160826183747j:plain

夜になるとよりよい。

LINE Pay は LINE ID: koba789 にお金を送ることができる良いサービスです。

はい

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 のような使い方をしたりということができるようになるんではないかと考えています。

それではまた。