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

いろいろバックエンドな人の備忘録

といいつつレイヤーのネタ書いてます。Ruby(RoR)、自宅サーバー,PCパーツ、ネットワーク、ピアノまで。

<Windowsネタ>Windows Subsystem for Linux はマルチスレッド対応なのか

★開発 ○Windows ○Linux

Bash はマルチスレッド対応?

Windowsbash が使えるようになってから久しい。 実は mac で事足りていたのであんまり使ったことがなかった。 今回、mac の調子が悪く、新しいものを購入する予算もないので(ピアノ買ったしね・・・)やむを得ず windows マシンで開発することにした。

きっかけは、新しいマシンでいつもやっている rbenv のインストールを行っていたときにCPUファンが周りだし ふとタスクマネージャーを覗いてみると、CPUのクロック数がターボ・ブースト状態(※1)になっていた。

今時のCPUは全コアを高クロックで動作させるのは熱や消費電力の問題があるようで、基本的に限界のクロック数で動いてはいない。 (詳しくはダークシリコン問題等で検索してほしい)

さて、そんなことよりターボ・ブーストがかかっているということは シングルスレッド で限界までCPUを食い尽くしていると見たわけだが これは、rbenv がシングルスレッドの設計なのか、 そもそも、bash.exe (しいては、Windows Subsystem for Linuxは)マルチスレッドに対応しているのかを知りたくなったので実験してみた。

※1シングルスレッドの性能を上げるために熱に余裕があればオーバークロックする機能

  • 6700k の定格は 4GHz だが 4.16GHz にブーストされている

f:id:nrtn:20170220145224p:plain

  • おなじみの rbenv のインストール

f:id:nrtn:20170220164916p:plain

Windows Subsystem for Linuxアーキテクチャ

Windows Subsystem for Linux とタイプするのが面倒になってきたので、以下:WSFL と書く。 WSFLのアーキテクチャは、検索すると沢山でてくるが要約すると システムコールレベルのエミュレーション であるようだ。

よくUbuntuVMが動作していると思われているがそうではないらしい。(私も誤解していた)

f:id:nrtn:20170220153219p:plain

上記の図は簡略図だが、簡潔に書くと Bash.exe が サービスを通じて、WSFL(lxcore.sys等があるようだ) を呼び出し 生成された Linux instance(インスタンス) 内の各Linuxアプリケーションを呼び出しているようだ。 あとは、普通のLinuxと同じく init->bash(シェル)->アプリケーション の順に動作しているよう。 ちなみに、アプリケーションが呼び出したシステムコール類は WSFLを経由して、最終的に Windows APIとして呼ばれる。

また インスタンスはユーザーごとに作成されるようだ。

(上記は筆者の解釈なので誤りがあればご指摘ください)

マルチスレッド対応の計測

で・・・

今回は最終的に Linux instance 内のアプリケーションのマルチスレッドがネイティブのWindowsでマルチスレッドとして動作するかを検証してみたい。

ネイティブのCPUをフルに使っていると判断するのはタスクマネージャーの各スレッド(ここではHTTのスレッド、コアを区別しない)をほぼ使い果たしていたら マルチスレッドに対応している ということにしたいと思う。

テスト

シングルスレッド

シングルスレッドのテストからしてみる。 なんの面白みもない普通の無限ループである。

/* single.c */
#include <stdio.h>

int main()
{
        printf("強制終了しないとおわらないよ♪");
        while(1);
}
gcc single.c -o single.out
./single.out

結果

  • 対象のCPUは 8スレッドなので 1/8スレッド=12.5% になるはずだが、他のプロセスも動作しているので若干それよりは高い

f:id:nrtn:20170220155116p:plain

  • こちらでは、 single.out が 13% と (ほぼ 1/8 スレッド) 専有している

f:id:nrtn:20170220164735p:plain

マルチスレッド

pthread をつかった、こちらも特に面白みのないコード。 CPUのスレッド分(今回は8スレッド)生成し、無限ループするだけ。

/* multi.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define CPU_MAX_THREAD  8

void* task(void *p);

int main()
{
                pthread_t threads[CPU_MAX_THREAD];
                int iret[CPU_MAX_THREAD], ii[CPU_MAX_THREAD];
                for(int i=0; i<CPU_MAX_THREAD; i++) {
                        ii[i] = i;
                        iret[i] = pthread_create(&threads[i], NULL, task, (void*)&ii[i]);
                        pthread_detach(threads[i]);
                }

                getchar();

                exit(0);
}

void* task(void* p)
{
        printf("Thread %d\n",*(int*)p);
        while(1);
}
gcc -pthread multi.c -o omulti.out -std=c99
./omulti.out

結果

  • 各コア100%食い尽くされている。

f:id:nrtn:20170220163903p:plain

スレッドの開始する順番は不定なので連番にはなっていないがバグではない。 (排他制御等を実装しない限り、必ずしもスレッドが作られた順番にスレッドが進まない)

:~$ ./omulti.out
Thread 0
Thread 2
Thread 1
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
  • 99% 使用されている。(このビューでは 100% になることはないので事実上すべてのCPUを専有している)

f:id:nrtn:20170220164033p:plain

まとめ

ちゃんとマルチスレッドで動作しているようだ。

なんだから改めて見返してみると当たり前のような気がするが、 VMであれば、仮想マシンに割り当てる vCPU などで想像はつくが、カーネルに埋め込まれたエミュレーションレイヤーであったので試してみた。

余談だがタスクマネージャー上では Linux のプロセス名(~.out) でプロセス名が上がっていたが、こちらの詳細やプロパティは表示されなかった。 (何も表示されなかった)

f:id:nrtn:20170220165634p:plain

<ひとりごと>ホスト名にIPアドレスつける?

★ひとりごと ★運用

ちょっと疑問におもったから書く。

命名するシチュエーション

IT業界で働いていると何かと一意の名前が必要になることが多い。 たとえば、

  1. プログラミングにおける変数名
  2. サーバーのホスト名
  3. ルーターのアクセスコントロールリスト(ACL)名
  4. アプリケーションのプロファイル名

など。

一般に業務でそれらを取り扱う場合は 命名規則 なるものを定義すると思う。 もしくは過去の慣習にしたがって命名すると思う。

今回はホスト名を例にだす。 命名問題はAWSGCPなどのクラウドに移行したとしても、命名の問題はずっとつき続ける。 皆さんはどのように命名しているだろう。

ホスト名にIPアドレス必要か

以前自分が担当してきたシステムではホスト名(VMのインベントリ名も)にIPアドレスの第4オクテットつける慣習があった。
例えば 10.11.12.13 のメールサーバーは mail13 という具合に。

自分はこの慣習がとても気持ち悪かった。

なぜなら、

  • IPアドレスは可変な性質がある
  • 増強時に構築の時期によって連番にならないことがある
  • その情報にあまり意味がない
IPアドレスは可変な性質がある

IPアドレスを固定にすればいいじゃんと思うかもしれない。
もちろん原則はそうなのだが、企業の買収などでシステム統合や移転などはIPアドレスを変更する必要がある場合が多い。 NATなどで無理やりIPアドレスの変更をしない設計もできなくもないが、通常はIPアドレスの変更で対処するはず。

増強時に構築の時期によって連番にならないことがある

例えば、はじめはシングル構成のWebサーバー(web2:192.168.0.2)をで運用し、 アクセス増加に伴い増強しようとした時、通常は(web3:192.168.0.3)などのように連番をつけると思う。

しかし、社内システムなどおなじセグメントに複数のシステムを入れている場合は、 既に別のシステムが使おうとしているIPアドレスを使用していることがある。

この場合、例えば192.168.0.4 で Webサーバーを構築し、先程の法則にそった場合は web2とweb4 になってしまう。

その情報にあまり意味がない

そもそも、ホスト名にIPアドレスの情報が必要だろうか。 重複排除目的にしてはには 1/256 の確率でで重複するし、 メリットといえばログインして ip addr コマンドで第4オクテットとホスト名が一致してたらちょっと安心するくらいである。

単語の羅列も悩ましい

他のシステムを担当しているものは [システム-構成名] 星の名前が多いと聞いた。 水金地火木土天海…の順番で命名すると決めた場合は web-mercury, web-venus, web-earth, という具合だそうだ。

これもちょっと疑問がある。僕みたいに星に詳しくない人はまず読みにくいし、 上記の例にメールサーバーを追加するときはまた水星から振り直しになって mail-mercry, mail-venus にするのか webで使った名称を継承して、mail-mers にするのかも決めて置かなければならない。

っというか、そもそもweb-01 web-02 では不都合があるのだろうか。。。

どこまで意味を持たすか

その情報に別の意味を付け加える時(ちょっとカッコつけて多重化とでもいおう)するときはよく考えたほうがいい。 iSCSIのターゲット名に日付が入っていたりすることがある。一見日付は無意味な情報に見えるが重複排除するという意味では意味があると思うし そもそも、iSCSIのターゲット名なんてそんなに見ないしのでそこまで考えなくていいような気もする。 (まあ、滅多にみないからこそ、忘れた頃にみてわかる命名が必要なのだが。)

<メモブログ> XenServer + Softether の注意事項

▲XenServer ★サーバー ★メモブログ

※加筆中

構築するにはプロミスキャスモードを有効にする必要がある

[root@xenserver ~]# xe pif-param-list uuid=<UUID★>
uuid ( RO)                       : <UUID★>
                     device ( RO): eth0
                        MAC ( RO): fe:ff:ff:ff:ff:ff
                   physical ( RO): false
                    managed ( RO): true
         currently-attached ( RO): true
                        MTU ( RO): 1500
                       VLAN ( RO): 301 ★VLANでも適用できる
             bond-master-of ( RO):
              bond-slave-of ( RO): <not in database>
       tunnel-access-PIF-of ( RO):
    tunnel-transport-PIF-of ( RO):
                 management ( RO): false
               network-uuid ( RO): <UUID★>
         network-name-label ( RO): (network)to ServerDMZ
                  host-uuid ( RO): <UUID★>
            host-name-label ( RO): hydro-dez
      IP-configuration-mode ( RO): None
                         IP ( RO):
                    netmask ( RO):
                    gateway ( RO):
    IPv6-configuration-mode ( RO): None
                       IPv6 ( RO):
               IPv6-gateway ( RO):
       primary-address-type ( RO): IPv4
                        DNS ( RO):
                 properties (MRO):
               capabilities (SRO):
                io_read_kbs ( RO): 0.108
               io_write_kbs ( RO): 0.000
                    carrier ( RO): true
                  vendor-id ( RO): 10ec
                vendor-name ( RO): Realtek Semiconductor Co., Ltd.
                  device-id ( RO): 8168
                device-name ( RO): RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
                      speed ( RO): 1000 Mbit/s
                     duplex ( RO): full
            disallow-unplug ( RW): false
               pci-bus-path ( RO): 0000:06:00.0
               other-config (MRW): promiscuous: true  ★これがついていればOK

https://support.citrix.com/article/CTX139535

<つぶやき>世知辛いですな

★日常ネタ ★ピアノ

下記記事がおもしろかった。 piano6789.hatenablog.com

このブログの一発目記事(※1)になったように、自分も社会人になってからピアノを再開した身であるし、教室探しに苦労したから共感できることは多かった。

※1 ITエンジニアがピアノを習い始めに行ったようです。(1日目) - いろいろバックエンドな人の備忘録

現在は某大手教室に通っている。 大手だとカラオケボックスのようにガラスドアの部屋が幾つかあるスタイルになっている。 なので、個人レッスンを受けつつセキュリティ(男が脅威になっているのは悲しいがそういう時代なのである)対策もできるという合理的な構成だとおもう。

恥ずかしながらピティナを知らなかったので、自分は会社の福利厚生サイトから見つけた。 (蛇足:福利厚生のプランは女性限定だったので使えなかったけどね。ここも男性には世知辛い世である。)

自分は、バレエ事件、アイドル殺傷、某芸能人の性的暴行事件などよりすこし前に入会していたが もし、今から入会するとなるともっと気を使うんだろうなあ。