Rubyのsleepが引数の時間より数倍かかってしまう

複数スレッドで同時にsleepを行ったとき、
sleepの引数の時間より数倍の時間がかかってしまう事があった。
いろいろと試行錯誤はしてみたけど、イマイチ理由はわからず…。
とりあえずメモだけしておく。

背景

今回のプログラムはとあるネットワーク上のサーバ、以下の4つのスレッドが存在しています。

  • 接続待機スレッド(accpet thread)
  • データ送信スレッド(send thread)
  • データ受信スレッド(recv thread)
  • メッセージルーティングスレッド(msg thread)

各スレッドはポーリングをしていて、それ以外の時間はコンテキストスイッチのために
定期的にsleepを入れるようにしています。
今回の問題は、この"定期的なsleep"です。

ruby-profで各スレッドの処理負荷を計測すると以下のとおりとなります。

接続待機スレッド(accpet thread)

 1Measure Mode: wall_time
 2Thread ID: 70010781717220
 3Fiber ID: 70010781716680
 4Total: 6.980623
 5Sort by: self_time
 6
 7 %self      total      self      wait     child     calls  name
 8 45.84      6.876     3.200     3.677     0.000       52   Kernel#sleep
 9  1.44      0.101     0.101     0.000     0.000        1   TCPServer#initialize
10  0.01      0.001     0.001     0.000     0.000       51   <Class::IO>#select

データ送信スレッド(send thread)

 1Measure Mode: wall_time
 2Thread ID: 70010781712700
 3Fiber ID: 70010781619120
 4Total: 5.175139
 5Sort by: self_time
 6
 7 %self      total      self      wait     child     calls  name
 8  1.94      5.174     0.100     5.073     0.000       52   Kernel#sleep
 9  0.01      0.001     0.001     0.000     0.000       17   IO#write
10  0.01      5.175     0.000     0.000     5.175        1   NodeSendTask#run

データ受信スレッド(recv thread)

 1Measure Mode: wall_time
 2Thread ID: 70010781622000
 3Fiber ID: 70010781619360
 4Total: 5.175198
 5Sort by: self_time
 6
 7 %self      total      self      wait     child     calls  name
 8 68.86      5.167     3.564     1.604     0.000       52   Kernel#sleep
 9  0.02      0.001     0.001     0.000     0.000       69   <Class::IO>#select
10  0.02      5.175     0.001     0.000     5.174        1   NodeRecvTask#run

メッセージルーティングスレッド(msg thread)

 1Measure Mode: wall_time
 2Thread ID: 70010781621200
 3Fiber ID: 70010781619380
 4Total: 5.175243
 5Sort by: self_time
 6
 7 %self      total      self      wait     child     calls  name
 8  0.02      5.173     0.001     5.172     0.000       52   Kernel#sleep
 9  0.01      5.175     0.000     0.000     5.175        1   MessageRouter#run
10  0.00      0.000     0.000     0.000     0.000       16   JSON::Ext::Generator::State#generate

問題点

今回sleepの引数は全て1msに設定しています。

上記のデータのうち、accept threadとrecv threadでsleepの回数に対する
時間がaccpetの場合60倍、recvの場合は70倍近くかかってしまっています。
1msのはずが約60ms。。。

おそらく、コンテキストスイッチの問題で遅くなっているのかなぁとは思っていますが、
それにしても時間がかかりすぎていてあまり納得はできていません。
もう少し調査方法を変えて見ながら探ってみたほうが良いのかも?

Posted at : 2016-01-05 14:40:26 / Category : none

年末年始はセブ島へ

セブ島へ年末年始は行ってきました。
寒いのが嫌いなので、暖かいところで過ごせたのは良かった。
日本帰ってきたら「寒い…」とばかり言っています。

セブ島は主に2箇所、日本人がリゾートで行くマクタン島と
あまり一般的ではない(と思っている)バンタヤン島に行ってきました。

前者はMaribago Bluewaterというところに泊まって、年越しもここで迎えました。
プライベートビーチがあることが売りの一つだったりするんですが、
水質が綺麗ではなく非常に良くなかったです…。
一方でプールで過ごせば、リゾート気分が味わえるので良いかなと思います。

いずれにしても、繁忙期にわざわざ行くようなところではなく、
閑散期のちょっと安めの時期を狙っていくのが良さそう…。

後者のバンタヤン島、これが非常に良かった。
まず、日本人含め全体的に観光客が少ない。
国内でのツアーの取り扱いがないし、ローカルバスに乗ることになるので
少し難易度が高いことが理由だと思う。
セブシティから路線バスに3時間のって、さらにフェリーで1時間近くかかる。
観光客が少ない分、ホテルやその島全体がのほほんとした空間になっていて、
普段の疲れを癒やすのには本当に良かった。

また、海の水もこちらは綺麗。海を楽しむための場所、という感じがして良かった。
今回泊まったホテルはMarlins Beach Resortというところ。
海側の部屋にしたら、テラスからすぐ海に出ることができるし、
そのままテラスで海を見ながらくつろぐこともできるので最高でした。
お値段的にも1泊2人で1万ぐらいなので、Maribagoとかに比べるとそりゃもう…。
ただ、お風呂とかトイレとかはダメだったかな。。。

という感じで、ホテル事情を中心に書いてみました。
まぁMarbagoが良くなかったという話ではなく
バンタヤン島が最高でした、っていう話でした(笑)
(サービスとか含めると、Maribagoは日本人が行きやすいと思います)

Posted at : 2016-01-04 23:57:59 / Category : none

今年も皆様お世話になりました!

今年も皆様お世話になりました!

今年一年を振り返ってみて、一番は結婚したことかな。
婚姻は3月、結婚式は9月でいろいろと準備が大変だった。
でも、思い返してみると楽しかったなぁ〜
また、いろんな方にご協力をいただいて、非常にありがたかったです。

あっという間の1年、気づくと年末だったなぁ…。
成果という点では、正直目に見えたものがあまり出ていない。
ただ、その下地となる考えや気持ちはまとまってきたと思う。
一つにはとにかくいろいろとやってみることかな。

もう26ということもあり、やっぱり焦る気持ちはある。
ただ、自分が面白い・役に立つと考えることをすべきと考えると、
自然のままに自分で考えて、それを形にできることが大切だと
この一年で思ったところ。

来年はそんな考えをまとめて、
結果を出せる一年にしていきたいと思います!

Posted at : 2015-12-31 19:33:43 / Category : none

I will go to Cebu!

Now, I'm moving to Narita Airport.
I will go to Cebu!
I will be relaax and getting energy to the new year.

セブ島に行くため、現在成田に移動中
今年一年の疲れをとって、来年の活力を貯めてきます~

Posted at : 2015-12-26 08:34:05 / Category : none

英語学習の状況

日本人がしゃべる英語であれば何とか聞き取れて、理解できるようにはなってきている
が、外人の喋る声がほとんど聞き取れないんだよなぁ…。いや、ほんとに恐ろしいくらい。。。

たぶん原因の一つに普段の勉強がNHK Radio Newsだったり、
英会話にしても日本人の癖がわかってる人(それでいて、日本人がわかるように喋ってくれる)だから
偏ってきちゃうんだろうなぁ
クリアな音は問題ないけど、つながった音(いわゆるリンキング)が聞き取りづらい

英語舌のつくり方 ――じつはネイティブはこう発音していた!
http://www.amazon.co.jp/dp/4327440841

これとかどうだろうかなぁ
スピーキングに焦点を当てている本だけど、規則を知るという意味で良さそう
(正直、日本人がスピーキングをそこまでこだわらなくても、
双方の必要性がある状況であれば聞き取ってくれることが多いとは思う…。
逆に、英語チックな日本語はどれだけおかしくても聞き取れるわけだし。。。)

あと、Podcastも変えてみようと思っていろいろと聞いてみて、BBCが良さそうかな
比較的クリアにしゃべっているのでまだ聞き取りやすいけどね。。。

Posted at : 2015-12-20 10:57:27 / Category : none

年末旅行のreconfirm

半年前に予約したので、念のためreconfirmの連絡をしてみた
行き先はフィリピン(セブ)、予約した3つのホテルにメール

結果、2件はエラーメールで弾かれる…。まぁそうだよねー

ひとまず、一番確認したかったところは確認できたので、
後は仮にダブルブッキングになっても諦めがつきそう
まぁそれも含めて旅の楽しみということで

Posted at : 2015-12-15 09:35:10 / Category : none

SQLiteの書き込みを早くする方法

事前に書き込むデータが決まっている場合(例えば、CSVからDBに入れる場合など)に早くする方法

一度In MemoryのSQLiteのDBを作成し、その中にデータを展開する
その後、SQLiteのBackupを使用して、DBの中身をファイルに書き出す
Rubyの場合は以下のサンプルコートが使える

http://www.rubydoc.info/github/luislavena/sqlite3-ruby/SQLite3/Backup

この方法は行数が多いデータ等には向いている
手元だと1500万レコードを追加するのに6時間ほどかかっていたのが
上記の方法を使って20分ほどに短縮することができた
要は、単純にdbへのwriteが遅かったってことだろうね

Posted at : 2015-11-23 19:31:20 / Category : none

携帯電話から聞こえる声は相手の本当の声ではないという話

某バラエティ番組でこの話が出ていて、何も解説がされていなかったので。
ざっくりと言ってしまうと、CELPが使われているからってこと。

Mobile:CELP【しーいーえるぴー、せるぷ】
http://www.itmedia.co.jp/mobile/0307/30/n_keywords.html

技術の立場からすると、逆に「特徴的な声から作ってるんだよ」と言えれば、
一般のかたにもわかりやすい表現になるね。

Posted at : 2015-11-08 22:49:06 / Category : none

git pullに関して思うこと

git pullに関していろいろと調べてみると、あれこれと書かれてるんですが、
正直まどろっこしいというかややこしいというか…。

git-pullは幸い(?)なことにシェルスクリプトなので、
echoを入れてコマンド見れば良いんじゃないかなと思うんです。

ということで、主によく問題とされている以下の2点について調べてみました。

  • git pull origin <branch>:<branch> をやってはいけない理由
  • git pullするとカレントブランチが更新される理由
    • さらに言うと、単純なgit pullだと追跡ブランチも更新される理由(「追跡ブランチ」は後述)

(本記事はgit version 1.9.5 (Apple Git-50.3)をベースとして記述しています)

以下のようなリポジトリ構成の場合、

1$ git branch -a
2  devel
3* master
4  remotes/origin/devel
5  remotes/origin/master

git pullは以下の結果となる。

1$ git pull origin devel:devel
2git fetch     --update-head-ok "origin devel:devel" || exit 1
3git-merge              "$merge_name" HEAD 312fc9f10fc4cba111d72f322d6a71147d34d976
1$ git pull origin
2git fetch     --update-head-ok "origin" || exit 1
3git-merge              "$merge_name" HEAD b909223d2d6094374e86bf32b036ff341ce149d6

git-merge

ここで注目するべきは2箇所。まず1つはgit-mergeの引数。
HEADにあるリビジョンをマージするから、 カレントのブランチにマージされるんです
git-pullのドキュメントにも

More precisely, git pull runs git fetch with the given parameters and calls git merge to merge the retrieved branch heads into the current branch.

となっている。
このことから、リモートブランチをpullすることを期待して、"git pull origin <branch>:<branch>"すると
カレントブランチにマージされてしまいます。
また、上記の事から"git pull"だけだとカレントブランチに対しての更新は、意図通りのものとなります。

git fetch

もう1つはgit fetchの挙動。
git fetchはoriginのみを指定した場合は、originの追跡ブランチをすべて更新し、さらに追跡ブランチに対応するローカルブランチを更新します。
詳細な説明は以下のとおり。

When git fetch is run without specifying what branches and/or tags to fetch on the command line,
e.g. git fetch origin or git fetch, remote.<repository>.fetch values are used as the refspecs---they specify which
refs to fetch and which local refs to update.
The example above will fetch all branches that exist in the origin (i.e. any ref that matches the left-hand side of the value,
refs/heads/) and update the corresponding remote-tracking branches in the refs/remotes/origin/ hierarchy.

git fetchだけを試しにやってみると

1$ git fetch origin
2remote: Counting objects: 3, done.
3remote: Compressing objects: 100% (2/2), done.
4remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
5Unpacking objects: 100% (3/3), done.
6From github.com:yasuharu/test
7   312fc9f..c1f1af3  devel     -> origin/devel

の通り、fetchだけでdevelは更新されます。
このことから、git pullするとカレントブランチ以外の追跡ブランチも更新されることがわかります。

追跡ブランチについて

以下のページが分かりやすかったです。

git pull しても更新されない

git pullしても以下のエラーで更新されない場合、追跡ブランチに登録されていないです。

 1$ git pull
 2There is no tracking information for the current branch.
 3Please specify which branch you want to merge with.
 4See git-pull(1) for details
 5
 6    git pull <remote> <branch>
 7
 8If you wish to set tracking information for this branch you can do so with:
 9
10    git branch --set-upstream-to=origin/<branch> devel

もし、リモートブランチが"origin"の場合、説明の通りにすればOK。

git branch --set-upstream-to=origin/devel devel

git pull時のmergeするリビジョン

リビジョンはgit fetchした後の、.git/FETCH_HEADから取得します。
「not-for-merge以外のもの」(=カレントブランチ)がmergeするリビジョンになります。

1$ git checkout devel
2Switched to branch 'devel'
3$ git fetch origin
4$ cat .git/FETCH_HEAD
5c1f1af3d7f4a02c252effb5ad8cdd390b541fff1                branch 'devel' of github.com:yasuharu/test
6b909223d2d6094374e86bf32b036ff341ce149d6        not-for-merge   branch 'master' of github.com:yasuharu/test
1$ git checkout master
2Switched to branch 'master'
3$ git fetch origin
4$ cat .git/FETCH_HEAD
5b909223d2d6094374e86bf32b036ff341ce149d6                branch 'master' of github.com:yasuharu/test
6c1f1af3d7f4a02c252effb5ad8cdd390b541fff1        not-for-merge   branch 'devel' of github.com:yasuharu/test
Posted at : 2015-11-03 09:46:16 / Category : none

NHK WORLD RADIO JAPANのScript

NHK WORLD RADIO JAPANのPodcastのscriptが無いと
以下の日記で書きましたが、実はほぼ同様のものがあることがわかりました…。

実はこの日記を書いたタイミングで、NHKの要望に「script公開してほしいなぁ」と
メールしまして、(日曜日にもかかわらず)1時間ほどで返事がかえってきました。
結論としては、NHK WORLD RADIO JAPANは以下のサイトで公開されている
原稿がもとになっているとのこと。

最新のNHK WORLD RADIO JAPANの配信と聴き比べてみたら、
確かに原稿の部分は全く同じものを流していました。
ただ、NHKからの回答によると以下のケースはあるらしい。

  • 配信時間の関係で一部カットされているもの
  • 掲載されている時間に制限がある(概ね最初のアップロードから48時間)

最後の制限は少し気になるけど、まぁ毎日聞くんであれば問題ないかな。

Posted at : 2015-10-18 17:21:30 / Category : none

transcript付きの英語学習向けpodcast

NHK WORLD RADIOを毎朝通勤の時間に聞いていて、内容は良い感じなんですが、
transcriptがないので聞き取れない単語があった場合、どうにもなりません。。。
ということで、transcript付きのものをいくつか探してみました。

おすすめはこのあたり。

以下は良いんだけど、Podcastで聞けないという難がある。
毎回ブラウザ開いて見れば良いんだろうけど…。

こちらはPodcastがある。興味とあわなさそうだったので保留

ちなみに、Androidの場合、おすすめのPodcastのアプリはPodcast Addictです。
気に入っているのは以下の点。

  • 再生速度が変更できる
  • N秒戻しができる(Nは自由に設定可能)
  • ロック画面で操作ができる
  • 自動ダウンロードに対応している
Posted at : 2015-10-18 17:04:59 / Category : none

ビジネスパーソンのための契約の教科書

仕事であれこれと契約書を読むことがあり、
契約書をどうするべきか?気になったので読んでみました。

ビジネスパーソンのための契約の教科書 (文春新書 834)
http://www.amazon.co.jp/gp/product/4166608347

重要なところをかいつまんで説明がなされていて良い本でした。
また、契約書がなぜ重要かという話も良かったけど、
それ以上に海外とのやり取りと日本の文化を比べながら
説明されているのが良かったね。

個人の契約でも、会社での仕事でも、一度読んでみると
契約書の大切さがわかって良いと思います。

Posted at : 2015-10-12 09:30:16 / Category : book

Dropboxへ直接アップロードするリンクを作る

大きなファイルをWeb上で公開する場合に、Dropboxへ直接アップロードするリンクが便利そう。

https://www.dropbox.com/developers/saver

上記の方法でリンクボタンを作った場合、
ファイルをダウンロードする際にローカルの保存先の選択をするように、
Dropboxの保存先を選択することができる。
保存しておくことが目的のファイルだと、結構便利。

Posted at : 2015-10-12 07:00:44 / Category : none

基板発注、その後

以前にピッチ変換基板を作ったと書きましたが、今週納品されるとのこと。
特に修正の指示とかなしできたけど、大丈夫なのかな…。
とりあえず見てからのお楽しみ。

ESP-WROOM-02用のピッチ変換基板を作る
http://yasuharu.net/diary/2820

Posted at : 2015-10-12 06:52:35 / Category : none

普段使いのMacBookAir(Mid 2011)をEl Capitanへ

普段使いのMacBookAir(Mid 2011)をEl Capitanへ変えてみた。
諸事情により、10.6からのアップデートになったものの、アップデート自体はとくに問題なく完了。
今日一日使ってみたところ、いくつかの問題に気づいた(10.6からアップデートしたことが問題かもしれないので、あしからず)。

  • VPNの設定がリセットされた
  • (アップデートした後に)現状でESETが対応していないことに気づいた

他にあれば加筆をしていきます。

Posted at : 2015-10-05 23:20:25 / Category : none

GENODE OSとGalliumドライバ

GENODE OS上でGalliumのドライバを動かせたという話
(記事を読む限りだと、4,5年前にはすでに実現していて
今でもメンテナンスされてますよ、って話なのかな)

Doing Graphics Hardware Acceleration With Microkernels
http://www.phoronix.com/scan.php?page=news_item&px=GPU-Microkernel-Support

まず、GENODE OSってのは知らなかった。
セキュアな環境を実現するためのMicrokernelなOS。
Microkernelにすることでカーネル自体のコード行数を減らし、
コードの検証をやりやすくする、ってことみたい。

まぁ、Micro kernelでもMonolithic kernelでも、
責任の所在がどっちになるかという問題のような気がしてて、
個人的にはどちらでも良いけど…。
(もちろん、見通しの問題もあるだろうけど、あまり利点があるとは思えない)

GalliumはLinuxのグラフィックスドライバのフレームワークの名称。
Mesa(Linux向けのOpenGLドライバ実装)の中に
このGalliumの仕組みを使ったグラフィックスドライバが実装されている。

この記事の面白いところは、Galliumの実行はLinuxでないと無理だろうなぁと
思い込んでいたけど、やろうと思えば他のOSでもできるという点。
ざっと見た感じだと、DRM(Direct Rendering Manager : Linuxカーネルドライバのうち
グラフィックスのリソースなどを管理するドライバ)に相当する部分を
Graphics Execution Managerという仕組みでユーザランドで実現している。
この辺りの話は2010年の以下の資料にのっていた。

http://genode.org/documentation/release-notes/10.08#Gallium3D_and_Intel_s_Graphics_Execution_Manager

極端な話、iTRONとか組み込み系のOSでもできなくはないんだろうな。

Posted at : 2015-09-25 11:48:22 / Category : none

ESP-WROOM-02用のピッチ変換基板を作る (3)

データをgithub上に上げてみました。
使ってみたい方はご自由にどうぞ〜

https://github.com/yasuharu/esp-wroom-02_conv_board

Posted at : 2015-09-24 11:37:11 / Category : none

ESP-WROOM-02用のピッチ変換基板を作る (2)

回路図、ボード図と実装完了したら、次にデザインルールのチェックをする。
EAGLE用のDRUファイルが以下にあるので、ダウンロードして使用する。

https://www.switch-science.com/pcborder/techguide/

最初はずらーっとエラーが出るので、一つ一つ対応していく。
今回作ったものだと、ほとんどがシルクとパッドが接触している、というエラーが多かった。
ライブラリの段階でダメなものが多かったので、
ライブラリをコピーして適当にシルクを修正した。

エラーが出なくなったら、最後に提出用データの作成。
上記のURLからCAMファイルをダウンロードしてきて、
CAM Processorからファイルを読みこませる。
(Mac版の場合、メニューバーからFile -> Open -> Job...を選択
上のメニューに出てると思わなかったので、一瞬わからなかった)
Proceed Jobを実行すると必要なファイルが出力される。

出力されたファイル

出力されたファイルで必要な物だけ取り出して、zipでまとめる。
これでデータの作成は完了。簡単にできるね…。

後はデータをアップロードして、先方からの確認がないか待つのみ。
ミスがないといいなぁ…。

Posted at : 2015-09-24 10:54:39 / Category : none

ESP-WROOM-02用のピッチ変換基板を作る (1)

ESP-WROOM-02というWifi付きのSoCが気になって、早速秋月で買ってきた。

Wi-Fiモジュール ESP-WROOM-02
http://akizukidenshi.com/catalog/g/gM-09607/

特徴は以下のとおり。

  • 安い(10個購入時で450円)
  • 技適に通っている
  • Wifi付きのSoCなので単体でいろいろとできる

ピンピッチが1.5mmなのでこれを変換する基板を用意する必要がある。
専用のものも探せば売っているので、それを使うのも一つの手。

と思ってたんだけど、そういえばこんなのあったな、と。

基板製造サービス「スイッチサイエンス PCB」ベータテスト開始 - スイッチサイエンス
https://www.switch-science.com/pressrelease/pcb_betatest/

9月中なら10枚たったの1713円で作れるという…。すごい。
今後使う可能性もあるので、ちょうど良いテスト基板として作ることにしてみた。

とりあえず、一通り作ったのがこんな感じ。

基板

Posted at : 2015-09-24 10:09:32 / Category : none

VPS再検討…が、現状のまま

今現在、VPSの契約が2つある

  • さくらのVPS / メモリ2GByte, HDDプラン
  • Conoha / メモリ1GByteプラン

どちらもそこそこ負荷はかかっているので、2つある事自体は問題なし。
ただ、気になってるのは、後者のほうの以下の点

  • メモリ1GByteだとたまに上限に引っかかる
  • ネットワークが遅い(というより、さくらが速いので相対的に感じる)

AWSにしようか、とか、いっそHerokuに一部移すかとかも
考えてみたけど、どちらもコスト的にいまいち。
動かしているサービスで利益が出ているのであれば、
投資と考えられるけど、現状は特に無いので最小限のコストで。
そうなると、現状のままでいっか…となりました。

Posted at : 2015-09-21 08:44:52 / Category : none