C++幼女先輩

プログラミング成分多め

#キャッシュレス社会を#求めて#クレジットカード整理し#ブラックカード目指す

はじめに

中国の人から、中国ではほとんどのものがウェイボー決済で買える。QRコード読み取って決済すると自動販売機から商品が出てくる ときき 驚いた 日本ではスマホを使った決済の場合は SUICAEDYFelicaのような Bluetooth的なもので行うが、iPhoneにはその機能がなく 独自でカード発行して自動チャージにするとか行う しかしQRコードならiPhoneでも出来る ローテクノロジーで解決させる さすが中国流と思った

そんなわけで日本のお店はカード払い出来ないところも多い 10年ほど前に一度 現金をほぼ持たず カードだけで生活を試みたが 高級なデパートでしか使えず苦労した覚えがあるが 今は SUICAなどで比較的小さなお店でもチャンスがある

キャッシュレス社会を作るために日本の弱点をさぐるために 再び キャッシュレスを目指すことにした

10年前より圧倒的に簡単なはずだ

それとついでに クレジットカードをまとめて、ついでなので ブラックカードを目指そうと思う

ブラックカード

とは、各クレジットカードで最高級のものである アメックスセンチュリオンは年会費30万、その他15万とか10万。そこそこの年会費がかかる ただし 完全招待制で、クレジットカードをよく使い 金持ち認定されると招待される サービスとしては コンシェルジュサービスで、例えば 六本木で8名でフランス料理ディナーの予約など頼むと いい店を見つけて予約してくれたり 上手く使えば 十分元とれる

しかし、楽天ブラックカードは 実質はプラチナカードレベルなんだが 見た目はブラックで、みんなから尊敬されかねない 年会費も3万程度と ネタに手に入れるには十分だろう いちおうコンシェルジュサービスもあるようだ

ということで 楽天ブラックカードを手に入れるプランを考える

カード整理

わたしは 無料有料ふくめ カードをいっぱいもっている。これでも沢山解約したんだけどね・・

セゾンが 無料、クラブオン、アメックスプラチナ エポス ゴールド 楽天 ゴールド ライフ ノーマル ビックカメラ ・・・

フリーランス時代に作れるうちに作っておけと いっぱい作ったが整理しきらん・・ 無料カードはそのまま残すとして アメックスプラチナは解約することにした。

そして 主に使うカードは3枚にした

楽天 プレミアムカード JCBEdy

ブラックにするために これは必須。JCBカードにしたのは nanacoへのポイントをするため。 nanacoで税金などを払うと楽であろう 下記の戦略のため 今年はあまり使わない プレミアムカードの特典として ファーストパスが利用できるので、空港でVIPラウンジいける ブラックにするインビテーション条件は謎で 年500万クレジットカード払っても来ないという人もいたり 挑戦してみようとおもう

Eposゴールド VISA

年50万程の買い物をすると 一生ゴールドが無料になる 多分招待されたので無料のはずだが 一度確認してくる もし無料になっていなければ 今年無料枠にするため 買い物がんばる たしか 持っているだけで旅行保険入るので便利

イオン ゴールド Master?VISA WAON

年会費無料。ただしインバイト必要 ノーマルカード(SUICAダメ)を作り 年100万等の条件をみたせばインバイトくる 年会費無料のゴールドなので取っておこう

その他

nanacoカード作る Suicaはとりあえず モバイルで、カードで払う。本当は ビックSuicaオートチャージしたいが・・

ロードマップ

楽天をプレミアムにするためには いったんノーマルを解約必要なので解約する nanaco契約 イオンカード契約 Eposカード 無料になっているか確認 定期的な支払いをまとめる。とりあえず楽天カード

Eposとイオンカードでそれぞれ 50万、100万 以上の買い物をがんばる 税金は楽天カード nanacoで払う

イオンとEposをゴールドにしたら 楽天カードに集約し ブラック目指す

Vulkan LunarG-SDK Sampleで勉強する 01-init_instance

あらすじ

前回 あらたにVulkanAPIを勉強する事にし、ドライバのインストールと 現在オフィシャルの LunarGという VulkanSDKをインストールし Sampleのビルドまで行った

ので、Sampleを参考に Vulkanの勉強をする

サンプル一覧

Samplesの下だけでも46個あった。 非常に多いのだが1つだけ注意点

なぜかこのサンプルたち、見た限りでは レンダーループが作られておらず 1秒後に終了するように作っている

おそらくは、WindowsAndroidLinuxに対応するために、レンダーループを共通化するのが面倒だったのでは? と思うが 真意不明

46個のサンプルのうち チュートリアルになっている15個から見てみよう

チュートリアル01は init_instanceで、Vulkanのインスタンスを初期化するサンプルのようである チュートリアルを順にならべると

init_instance Vulkanインスタンスの初期化 enumerate_device デバイスの列挙 init_device デバイス初期化 init_command_buffer コマンドバッファの初期化 init_swapchain スワップチェインの初期化 init_depth_buffer 深度バッファの初期化 init_uniform_buffer Uniformバッファの初期化 init_pipeline_layout パイプラインレイアウト初期化 init_descriptor_set でスクリプタセット初期化 init_render_pass レンダーパス初期化 init_shaders シェーダー初期化 init_frame_buffers フレームバッファ初期化 init_vertex_buffer 頂点バッファ初期化 init_pipeline パイプライン初期化 draw_cube キューブ描画

やれやれ・・ たかがキューブ描画のために、初期化こんなにあるのか・・

01-init_instance

#include <iostream>
#include <cstdlib>
#include <util_init.hpp>

#define APP_SHORT_NAME "vulkansamples_instance"

int sample_main(int argc, char *argv[]) {
    struct sample_info info = {};
    init_global_layer_properties(info);

    /* VULKAN_KEY_START */

    // initialize the VkApplicationInfo structure
    VkApplicationInfo app_info = {};
    app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    app_info.pNext = NULL;
    app_info.pApplicationName = APP_SHORT_NAME;
    app_info.applicationVersion = 1;
    app_info.pEngineName = APP_SHORT_NAME;
    app_info.engineVersion = 1;
    app_info.apiVersion = VK_API_VERSION_1_0;

    // initialize the VkInstanceCreateInfo structure
    VkInstanceCreateInfo inst_info = {};
    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pNext = NULL;
    inst_info.flags = 0;
    inst_info.pApplicationInfo = &app_info;
    inst_info.enabledExtensionCount = 0;
    inst_info.ppEnabledExtensionNames = NULL;
    inst_info.enabledLayerCount = 0;
    inst_info.ppEnabledLayerNames = NULL;

    VkInstance inst;
    VkResult res;

    res = vkCreateInstance(&inst_info, NULL, &inst);
    if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
        std::cout << "cannot find a compatible Vulkan ICD\n";
        exit(-1);
    } else if (res) {
        std::cout << "unknown error\n";
        exit(-1);
    }

    vkDestroyInstance(inst, NULL);

    /* VULKAN_KEY_END */

    return 0;
}

短いので全部乗せた。 初回なので少しだけ丁寧に

vkで始まる関数がVulkanのAPIである かなりC言語臭いが、それをラップしてC++っぽくしたライブラリもあるので今度紹介する

#include <util_init.hpp>

これはサンプルの独自のUtilであるが、大したことをしていない。今回で言えば sample_mainの定義がある程度

ここで少し気になる sample_main() という関数 そう、エントリーポイント関数がないやん? きっとこれがエントリーポイントだろ? すぐわかるが、一応調べると

#ifndef __ANDROID__
int main(int argc, char **argv) { sample_main(argc, argv); }
#endif

Android以外は単純に sample_mainを呼ぶだけである

Androidの場合は Android_handle_cmdで sample_mainを登録したり NDKから呼ぶため特別処理になっている

とりあえずは sample_mainはエントリーポイントだと思って良い

レイヤー列挙

init_global_layer_properties(info); の中身は

    do {
        res = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
        if (res)
            return res;

        if (instance_layer_count == 0) {
            return VK_SUCCESS;
        }

        vk_props = (VkLayerProperties *)realloc(
            vk_props, instance_layer_count * sizeof(VkLayerProperties));

        res =
            vkEnumerateInstanceLayerProperties(&instance_layer_count, vk_props);
    } while (res == VK_INCOMPLETE);

    /*
     * Now gather the extension list for each instance layer.
     */
    for (uint32_t i = 0; i < instance_layer_count; i++) {
        layer_properties layer_props;
        layer_props.properties = vk_props[i];
        res = init_global_extension_properties(layer_props);
        if (res)
            return res;
        info.instance_layer_properties.push_back(layer_props);
    }
    free(vk_props);

    return res;

となっている。 まずレイヤーとは何かだが、まだ詳細につかめていないが Vulkanのコマンドに割り込んで色々なことをするものらしい 例えば デバッグに使う

vkEnumerateInstanceLayerProperties の2番目の引数にnullptrを入れると、取得可能なレイヤー数が取れるので レイヤー数を取得したあと reallocで個数分確保している まことにC言語である

列挙中に極まれにレイヤーが追加されることがあるらしく VK_INCOMPLETE が返ってきたら、カウントからやり直すようになっている

インスタンス作成

vkCreateInstanceを呼ぶことで、Vulkanのインスタンスを作成する これが チュートリアル01のゴールだ。

インスタンス作成は単純で、VkApplicationInfoとVkInstanceCreateInfo を設定して渡せばよい 第一引数に VkInstanceCreateInfo  第二引数は 通常はnullptrでよい。必要があれば下記 MemoryAllocationを読む事 第三引数に Vulkanのインスタンスが入る

MemoryAllocation https://vulkan.lunarg.com/doc/view/1.0.33.0/linux/vkspec.chunked/ch10.html

vkDestroyInstance でインスタンスを解放すれば終了

初回なので丁寧に見たが、面倒なだけで そこまで難しくはなさそうだ

Vulkanほんと入門!

はじめに

3D APIは複数あります

OpenGL

OpenGL、OpenGLES、WebGL等 色々と出ているがどれもがクロスプラットフォーム 現状 WindowsLinuxMacAndroidiOS、Web が動くのはこれしかない コンシュマーゲーム機でも採用されている 現在 WebGL1.0(GLES2.0)が主流だが、WebGL2.0(GLES3.0)も 動くブラウザが増えている

非常に簡単にコーディング出来るし、各種ラッパーライブラリもあり便利な反面 APIが高レイヤーすぎてパフォーマンスに問題がある 今後は速度を劇的に改善したVulkanへ移行されていくと思われる

その為、私は選択肢から外した

DirectX

Windows OS上で動くグラフィックAPI 現在は バージョン12まで出ている 非常に低レイヤーで最も速度が速いし さすがMicrosoft様、ライブラリも速度のわりに使いやすい またC++でラップされている。当然すべてスマートポインタ(COMポインタ)になっており メモリ開放も比較的容易 問題点は Windowsでしか動かない事

Mantle API

AMDの提唱した低レイヤーAPI 速度はかなり高速らしいが、普及率で下火になり Vulkanへと引き継がれる

Metal API

最初AppleはVulkanプロジェクトに入っていたが、Appleが脱退し 独自のAPIを作る そのため Metal APIApple製品でしか使えない Vulkanから分裂しただけあって、Vulkanとかなり似ている

Vulkan API

クロノスグループにより、OpenGLの後継APIとして標準化される MetalAPIを基本にした高速APIである WindowsLinuxAndroidで動く。 また Webで動く WebVulkanも開発されているらしい??

Apple製品以外はすべて対応していて、OpenGLとは比べ物にならない速度である DirectX12よりほんの少し遅いらしいが 誤差範囲

ということで、これからVulkanを勉強しようとおもう

環境構築

まず 私の環境は RazerBladeというノートPC ビデオは GeForce1060 Windows10である WindowsLinuxで、Kepler以降のGPUが必要だ。 以前はGPUの乗ってないWindowsとMacbookProしか持っておらず開発出来なかった RazerBladeを手に入れた今は 誰も邪魔するものはいない!

NVidiaより Vulkanドライバをインストール Vulkan Driver Support | NVIDIA Developer

Valveが開発協力した?という LunarG SDKを使う。私の知る限りこのSDKしか存在しない https://vulkan.lunarg.com/

サンプルがいっぱいついているが、実行するためにはCMakeなどが必要 VisualStudioさえインストールされてあれば Demos以下は実行可能である CubeにLunarGと書かれたテクスチャがはられたデモが表示されるはずだ

プロジェクトTemplate作成

VisualStudioのテンプレートも用意されている プロジェクト新規作成時にVulkanのパスの通ったプロジェクトを作成できる 便利なのでぜひ行っておきたい

SDKPATH/Templates/Visual Studio 201x にあるZIPファイルを ドキュメント\Visual Studio 201x\Templates\ProjectTemplates\Visual C++ Project に全部コピーしてVisualStudioを立ち上げなおすと New Projectを作った際にVulkanがテンプレートに表示される

サンプルを実行する

https://vulkan.lunarg.com/doc/sdk/1.0.39.1/windows/getting_started.html

に書いてあるように CMake 3.0 以降、Python3.0以降、VisualStudio2013 Update4以降 が必要

CMake

https://cmake.org/download/ ここから Windows用をダウンロードしインストール CMakeのパスを設定するか聞かれるので、設定しておこう

Python

Windowsは下記より。くれぐれも 3.0以降を入れる事 Python Releases for Windows | Python.org

ビルド

上記をインストールしたあとは VisualStudioとCMake、Pythonにパスを通したコマンドプロンプト 具体的には VisualStudioに VS20xx用MSBuildコマンドプロンプト 等を実行し SDKPATH/Samplesへいき build_windows_samples.bat を実行する

エラー!!

CMake Error at C:/Program Files/CMake/share/cmake-3.8/Modules/FindPackageHandleStandardArgs.cmake:137 (message): Could NOT find PythonInterp: Found unsuitable version “1.4”, but required is at least “3” (found C:/Program Files/Emscripten/python/2.7.5.3_64bit/python.exe) Call Stack (most recent call first): C:/Program Files/CMake/share/cmake-3.8/Modules/FindPackageHandleStandardArgs.cmake:375 (_FPHSA_FAILURE_MESSAGE) C:/Program Files/CMake/share/cmake-3.8/Modules/FindPythonInterp.cmake:149 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) Sample-Programs/Hologram/CMakeLists.txt:1 (find_package)

Emscriptenを入れていてそっちのパスを見に行っている EmscriptenをアンインストールしCMake入れなおしたが 上記エラーが続き とりあえずあきらめた・・・

WindowsPython どうすればいいんだろうか・・・

解決

CMakeCacheにごみが残っていたので、削除してビルドしなおしたらうまくいきました。

Samples\build以下に プロジェクトが作成されるのでサンプルをビルドできます

ただし、VK_LayerOverlayだけはビルド出来ませんでした でも現状問題ないので このままサンプル見て勉強です!

boost::bind (std::bind)を理解する

はじめに

C++で仕事をしていますが、C++って人によって理解度が違います 今回の案件はBoost.Asioで作れという指定なので、どうしてもC++色が強くなります

stream、string、functional、bind、rambda はたまた triboolやtuple、各種コンテナと

他の作業員がC++読めないので 事細かに説明していますが その中でも 最も説明が難しいものの1つが bind等の functionalでしょうか

ってことで、他の作業員への説明資料作成の下書きに ブログにはりつける

bindって?

大雑把にいえば 指定された関数から std::function を作るもの ですがよくわかりませんね 色々便利な関数ポインタ(実際は関数オブジェクトだが)を作るものということです

std::bind と boost::bindがありますが、似たようなものです 元々boost::bindがあり、とても有用なため標準ライブラリ入りしました 大きく違うのは、引数が stlだと std::placeholders::1 と長いですが boostだと 1 と、グローバルネームスペースにあり短いです

大きく2つのメリットを書いておきます

引数を束縛する

bindの名前の由来です

例えば int 2個の引数からなる関数の 第一引数を 2で固定するとか、引数の順番を変えたりとかできます

void hoge( int a, int b ){ std::cout << "arg1=" << a << "   arg2=" << b << "\n" }

auto fn1=boost::bind(hoge, 2, _2); // 第一引数を 2に束縛
auto fn2=boost::bind(hoge, _2, _1); // 引数の順番を逆に!

fn1(5);  // arg1=2  arg2=5  と出力
fn2(1,2);  // arg1=2  arg2=1  と出力

関数型言語のカリー化風なことができましたね

クラスのメンバ関数のポインタを グローバルスペースで使える

何を言っているかわかりませんね クラスのメンバ関数のプロトタイプには、クラススコープが付きます

例えば

struct C {
    void hoge() {}
};

この hogeのプロトタイプは void()() ではなく、void(C::)() です。

なので 下記

struct C {
    void hoge(int n) {}
};
struct C2 {
    void hoge(int n) {}
};

void(*fn)(int) = C::hoge; // Error
void(C::*fn2)(int) = C::hoge; // OK
void(C::*fn3)(int) = C2::hoge; // NG

クラスが固定ならば、上記の クラススコープ入りの関数ポインタで問題ないけど 例えばコールバック等で汎用的なインタフェース作ると困りますね そんな時に bindを使えば、引数が同じであれば クラススコープが異なっていても 同等に扱うことができます ただし、thisポインタが誰であるかを知る必要があるので 第二引数にそのクラスのthisポインタが必要です

struct C {
    void hoge(int n) {}
};
struct C2 {
    void hoge(int n)  {}
};

void hoge(int n){}

C c;
C2 c2;

std::function<void(int)> fn1,fn2,fn3;   // 全部同じ型
fn1 = boost::bind(hoge, _1); // OK  グローバルのhoge関数
fn2 = boost::bind(&C::hoge, c, _1); // OK
fn3 = boost::bind(&C2::hoge), c2, 5); // OK  当然引数も束縛出来る

std::function は、関数オブジェクトのラッパーである。関数オブジェクトは 大雑把にいうと関数ポインタの高機能版である

とりあえず これにより、異なるクラススコープのオブジェクトであっても、引数が同じであれば同じに扱うことが出来る

bindを使わない実装例

例えば Threadの作成などで、グローバル関数から クラスのメンバを呼ぶことがある この時 thisポインタが不明になるので色々と工夫をする必要がある global変数にthisを入れると、オブジェクト1つしか扱えないので却下。では リストで管理する? 面倒で不具合のもと ということで よく、staticのコールバック関数に void*型の引数を作り thisポインタを渡し Castして使う

struct Hoge{
  static void callback(void *self, int n){ static_cast<Hoge*>(self)->hoge(n); };
  void hoge(int n){};
};

setCallback( void(*fn)(void*,int), void* self){
  *fn(self, 5);
}

Hoge h;
setCallback( Hoge::callback, &h );

なんとなくダサいと思ったらその感覚は正しい 上記は function、bindでは こう書ける

struct Hoge{
  void callback(int n){ hoge(n); };
  void hoge(int n){};
};

setCallback( std::function<void(int)> fn){
  *fn(5);
}

Hoge h;
setCallback( boost::bind(&Hoge::callback, &h ));

thisポインタをコールバック側で受けてCastする事もなく、static関数を使うこともなく きれいに書ける

関数オブジェクトとは

functionを理解するには必要

要約すると クラスにoperator()をオーバーロードし、あたかも関数のように見えるオブジェクトである

struct FUNC {
    int operator ()(int n) {
        cout << "operator " << n << endl;
        return n;
    };
};

FUNC f;

f(2); // 関数呼び出しっぽく見えるがメンバ変数の operator(int)を呼び出している

この目の錯覚をつかい 人間にはあたかも関数ポインタだと思わせるのが関数オブジェクトである

その関数オブジェクトを使い、bindっぽい事をしてみる

struct C {
    void hoge(int n) {
        cout << "C::hoge  " << n << endl ;
    }

};

template<class T>
struct FUNCOBJ {
    T *self_;
    FUNCOBJ(T* self) : self_(self) {};

    int operator ()(int n) {
        self_->hoge(n);
        return n;
    };
};

C c;

std::function<int(int)> fn1 = FUNCOBJ<C>(&c);

fn1(5);

このように、一度 C::hogeを呼び出す関数オブジェクトを作り、thisを関数オブジェクトのメンバとしてキャプチャすれば 関数ポインタのように関数オブジェクトを扱うことが出来る。

bindは、引数のテンプレートを処理したり、非常に複雑で中身を理解しきれないが大雑把には 関数オブジェクトを作成し メンバ変数をWrapしている

また、C++11では関数オブジェクトを簡単に書くことが出来る ラムダ関数があるので上記は こう書ける

C c;

std::function<int(int)> fn1 = [&c](int n) { return(c.hoge(n)); };

fn1(5);

ちなみに上のコールバックはラムダだと

struct Hoge{
  void callback(int n){ hoge(n); };
  void hoge(int n){};
};

setCallback( std::function<void(int)> fn){
  *fn(5);
}

Hoge h;
setCallback( [&h](int n){ h.callback(n);} );

WebAssembly Windows環境構築

Windows環境を作るにあたって

公式ページでは下記のように http://webassembly.org/getting-started/developers-guide/

The instructions on this page are applicable to Linux and Mac OS X systems. Similar instructions for Windows systems are forthcoming.

Windows環境の構築については まだ手順がなさそうなので 挑戦してみます

構築

基本的には公式の LinuxMac環境構築を参考にします http://webassembly.org/getting-started/developers-guide/

ChromeのWebAssembly有効化

chrome://flags/#enable-webassembly と Chromeで入力し WebAssemblyを有効にし 再起動させる!

emsdkをインストール

https://kripken.github.io/emscripten-site/index.html

ダウンロードページよりWindowsバイナリを入手しインストール インストール時にパスも通してくれるので 私は通した。

emsdkのパッケージ更新

Linuxの手順で行うと、gitがないと怒られたので、gitも入れます

> emsdk update
> emsdk install git-1.9.4
> emsdk install clang-incoming-64bit emscripten-incoming-64bit sdk-incoming-64bit
> emsdk activate clang-incoming-64bit emscripten-incoming-64bit sdk-incoming-64bit

一通り環境整ったはずなので テストします

emsdk テスト

上記の公式をもとに、Cでソースをかきます たとえば hello.c を作成

#include<stdio.h>
int main(int argc, char ** argv ){
  printf("Hello, world!\n");
}

ビルドします

> emcc hello.c -s WASM=1 -o hello.html

結構コンパイル時間かかったし Warningもいっぱい出ましたが無事ファイルが複数できました before.js、hello.html、hello.js、hello.js.temp.js の4ファイルが私の環境ではできました。 このうちの hello.htmlが目的のものなので ブラウザで表示しましょう。

Apache等あればそこで表示してもいいです 公式では pythonを使って

> python -m SimpleHTTPServer 8080

ブラウザより localhost:8080/hello.html

をたたくと、Emscriptenウインドウに Hello,World! が表示されるはず。 表示されたら成功! おめでとう!

とのことらしいですが、期待していたバイナリが出ていないような・・・

> emcc -O2 hello.c -s WASM=1 -o hello.html

と、最適化オプションつけると hello.wasm、load-wasm-worker.js、hello.html.mem などの 怪しいものが出てきます・・

このあたり 一度調査必要ですね

とりあえず公式的には環境完成のようです

おれはMacbookをやめるぞ!ジョジョーーッ!!

Macbookやめました

まずはMacbookを手に入れる所から

Macbookが必要になった事

私はずっとWindowsを愛用してきた。もちろん CygwinLinuxを内部にインストールしLinuxも使っていた Macさんの事は話で聞いていたものの、特にWindowsでも困ったことがないし、仕事もWindowsで十分食ってたので Macさんは触ったことがありませんでした

ところが iPhoneが出て、iPhone用のアプリを開発するために Macが必要になりました 2011年の暮れに、当時常駐案件を請けていたM社にて ”自作のレンダリングエンジンをAndroidiPhoneに移植してくれ” というオーダーが下った

自作のレンダリングエンジンは DirectX11と8086アセンブラSIMD、CUDA等を使って書かれており Android/iOSに移植するには 3Dエンジンを OpenGLES2.0(開発当初は 1.5しか出てなかったので1.5)に変更し 8086アセンブラを ARMに変更。 MASM記法からGas記法にも変更・・ SIMDは Arm用のNEONに書き換え CUDAは GPGPUは当時はスマホで安定して使えなかったため廃止

こんな 大変なオーダーだったんですが一番困ったのは iPhoneアプリ開発にはMacが必須! 私はMac持ってないし触ったこともなかった事

Macbook買うぞ

2011年も終盤にさしかかった時に仕事のために購入を決定した 仕事で使うので AirではなくProにした サイズは 15インチがちょうどバランスが良いと思った

Retinaが出たばかりの頃で、Retinaモデルは非Retinaモデルかで悩んだが、Retina基板が必要なため 非Retinamモデルにはあった光学ドライブRetinaモデルではなくなっていた 光学ドライブは仕事に不要なので 分解しドライブを外し、かわりにSSDを装着させ 256GBのSSD+1TBのHDD でFusionDriveを作る改造をすることにした。当然SSDは評判の高いIntelのSpeedDemonだ! ついでにメモリも搭載可能なMAXに増やして RAMドライブを作り ボクの考えた最高のMacbookProを手に入れた!

MacbookProとの生活

初めてのMacで戸惑うかと思ったが、実はWindows8よりも Windowsらしく、Windows7とまったく同じように使えた。 さらに Bashが付いていて CygwinWindowsよりも快適であった! 肝心のC++コンパイラ XCODEは VisualStudioに比べると格段に貧弱であったり、いろいろ不満点が無いわけではないが MBPとの生活はとても良かった 仕事にいくにも 遊びにいくにも、常に背中には MBPを背負い。 重さも2キロ少しで、軽い筋トレ程度である 電源アダプタは1個8千円もして 足元みられてるなーと思ったが、家用、職場用、持ち運び用と 3個買った。 2011年の暮れから Android/iOSの仕事をたくさん請けて、Macbookが無ければ仕事にならない状態だった

少し状況がかわってきた

2013年の頭から、iOS技術者というのが増え、iOSの開発しかしない(出来ない)人があふれてきたように思う 私の周りでは、どちらかというと Android技術者が不足していたため ほぼAndroid一本になる 2014年頃からは ゲームサーバー案件で、JavaC++を使った案件も増えた UNITYやcocos2d-x、WebGL案件もこなした。 この頃から Macが必須ではなくなっていたが、MBPはかわいいし、パフォーマンスも良かったので愛用していた

先天性の病気みつかる

買った当初から困った現象があった スリープしたあとレジュームできず落ちたり、起動しているが画面がつかなかったり 急に再起動したり けっこう困っていたが、我慢できないレベルではないので我慢していたが 購入から3年以上すぎてから Appleはビデオに関するロジックボードの不具合をみとめ 無料修理をはじめた ところが 私のMacbookは 買った初日に魔改造したため、無料修理の対象外らしく 交換してもらえなかったし 仕事も常に回っていたので 1日たりともMBPを手放せる状態ではなかった

そして伝説に

2015年に 何度か立ち上がらなくなり ごまかして使っていたが 2016年6月 完全に沈黙してしまった 一応 AppleStoreで話きいてくるが きっと修理ダメだろう。 金だせば修理してくれると思うけど このまま文鎮にするぞ! 安らかに眠れ R.I.P SSDとHDDとメモリだけ 取り出そう

交代要員1 Lavie Tab W

2015年 MBPが調子わるいので、万が一の事を考え 予備マシンの検討をした 同じくMacbookにするのが最初の考えだったが iOS案件を2年請けてなかった事 必要になれば買えばいいや とのことで、使用目的を完全にしぼることにした。

当時は打ち合わせも多く、お客さんのところによく出入りしていたため 軽くて移動させても壊れにくいPC SSD搭載のタブレットPCに決めた 各社タブレットPCがあったが、最も軽く タッチペンがワコム搭載で 高性能な Lavie Tab W に決定した 重さはなんと500gちょい! キーボードつけても900g程度! 旅行にもちょうどいいね! 魔改造して SIMを挿せるようにする予定だったが、テザリングでいいやってことで 改造していない タブレットPCゆえに スペックは低く、開発には向かないが なんとか開発につかえた JavaScript等の案件には十分だった

ただ、OSがあえての32bit(メモリを効率的に使うためにスペック低いマシンでは多い)のため 開発ツールが動かないものが多いのが難点

RazerBladeとの出会い

UnrealEngine4の仕事を始めた。当然 タブレットPCで動くわけもなく。 ただただUE4が快適に動くPCを探した MacOSでは UE4はちゃんと動かないため WindowsのゲーミングPCしか選択肢がなかった 色々なゲーミングPCをみたが、問題は重量と形状だった。 たいていのゲーミングPCは重い! 筋力で解決すればよいが、限界がある。毎日4キロのPCなんて持って歩きたくない そして ゲーミングPCといえば あえてのゴツいデザインが多く、カバンに入れて持ち運ぶのが面倒だった

そして 色々悩んでいたら 見つけました! 軽くて、シンプルデザインで、スペックすごく高い奴 Windows版のMacbook、黒いMacbookともいわれる RazerBlade 重さは 2キロちょいと Macbookと同じか少し重い程度で CPUはcore i7 6世代。GPUはなんと Geforce GTX 1060搭載。 しかも ビデオに低負荷状態の時は 省エネの オンチップGPU Intel 530を使うという とても賢い仕様

ところが問題は、日本では発売されていないの事! Amazon.comで購入を試みたが、あと一歩のところで リチウムイオンの輸出規制などで購入拒否される 色々な輸入方法を探していたら、公式が日本で通販をはじめた! ただし 入荷未定・・

すると ツクモがRazer専門店をオープンするとのニュースが! 初日にいき PCを買おうと現金もっていくも 入荷するかわかりません。予約だけ承っております・・・

とりあえず 予約だけしておいた

そして 本当に年末。12月の末に、日本の公式ページにて 販売開始アナウンス! 価格は 税込み26万 MacbookProの新型と同じぐらい。許容範囲だ

迷わず買った

その数日後にツクモより、販売決定したとの連絡があった

そして 今 RazerBladeから書いている。

ドラクエもFFも すべてのベンチマークが、超快適になる。 すごいノートPCだ UE4もUNITYもサクサク動く すべてにおいてパーフェクトだ そして Macbookとちがい、ゲームができる!

すごい! RazerBlade 最高!

こうして Macbookを辞めた

WebAssembly 調査!

新年一発目は WebAssembly

今年(会社自体は6月はじまりなので 2016年度下期)に、会社の方針として C++アセンブラの高度な技術を一番の武器に活動することを決めました もちろん今までのようにゲームが主軸になると思いますが ゲーム&ビジネス限定せず 今まで以上にC++を頑張ろうとおもいます

そんな中で気になるものが WebAssembly

今までJavaScriptしか動かなかったブラウザにおいて、ネイティブに近いバイナリフォーマットが制定されたようです 一言でいうと とても速くなるらしいですが、ほかにも色々な似たテクノロジがあるので 簡単にまとめます。 間違ってる部分あったらごめん

最初のJavaScript

元来ブラウザは静的な表現しか出来なかったが、JavaScriptの登場により、動的に変更する事ができるようになった Mozillaが開発したが、すぐさま IESafariと追従し、後にGoogleChromeを作った際も対応していた 当初は 個人のホームページで遊び要素程度に思っていたが、ブラウザを使ったビジネスアプリやサービスが増え JavaScriptは主役になったが、インタプリタ実行のため非常に遅かった

Flash(ShockWave)

Adobe ブラウザ上でネイティブのように動くVMの先駆け 息が長くほとんどのブラウザでサポートされていたが、突然Macが対応を終了しHTML5

JavaApplet

Sun ブラウザ上で動くJavaVM

ActiveX

Microsoft。 他のブラウザが対応しなかったため IEの特定バージョンでしか動かない COMテクノロジ(.netの前身)VM上で動く

v8エンジン

GoogleJavaScriptを高速実行するためのエンジンを開発 JITコンパイルにより ロード時にネイティブコードに変換されるため 実行速度は非常に速い また サーバサイドにJavaScriptを使った node.jsも作られる

HTML5WebGL

HTMLが色々と見直され 色々と高速かつ便利になり、Flash等のVMが不要になった ブラウザ上で高速な描画が可能に。 OpenGLES2.0とほぼ同機能がJavaScriptで提供された。

ES6

JavaScriptは、小さなものを作るには楽だが、大規模開発には色々と問題がある 変数は基本的に全部グローバルであり、ネームスペースの概念がない オブジェクト指向に慣れている人には Classが存在しないのも使い勝手が悪い それらの問題を解決するために、JavaScriptの新しい規格が登場した しかも Babelなどを使い、ES5にトランスパイル可能なので 古いブラウザでも実行可能に

NaCl

Googleが作った。 LLVM技術を使い、Emscripten等で C++からブラウザ用のネイティブバイナリを作り、ブラウザ上でネイティブ実行される ネイティブなので当然とても速い ただし、対応していないブラウザでは実行することができない WebAssemblyと同じ思想のように思えるし、WebAssemblyよりも速いかもしれないが Chrome以外に搭載されず 消える運命に。

Asm.js

Mozilla製。 NaClに対抗して作られた 型情報付きのJavaScriptサブセット JITコンパイルにより劇的に高速になったJavaScriptだが、型情報がないためネイティブには全く歯が立たなかった。 型情報を追加することで、ネイティブのおよそ1.5倍程度の速度まで迫ることができた しかも 非対応ブラウザでも普通のJavaScriptとして動作する ただし、人間が手で書くには困難なため、C++等からEmscriptenを使い変換する

WebAssembly

GoogleMozillaMicrosoftApple が共同開発!! NaClに似た思想で、JavaScriptバイナリにする おそらく NaClと違い完全にネイティブコードにせず、中間言語にとどめ 各社ブラウザがJITコンパイル しやすくしている Asm.jsと同じく 型情報も持っている。ネイティブと比較し1.1~1,2倍程度らしい ここで勘違いしてはいけないのは、バイナリになったから実行速度が上がるわけではない事。 元々JITコンパイルされているので、JavaScriptは実行速度は速い 速くなるのは バイナリコードになりデータ量が少なくなったことと、中間言語なのでコンパイル時間が劇的に向上する事によるものである おそらく、ロード時以外はあまりAsm.jsと変わりがないと思われる 今現在は C++からLLVM経由でコンパイルする事しかできないが 順次色々な言語で対応される Rustが対応開始したらしい

まとめると

今まで色々とJavaScriptの高速化や ネイティブアプリの実行があったが、ブラウザ各社の足並みが揃わず終了したが WebAssemblyはほぼすべてのブラウザメーカーが共同開発しているため、期待がもてる JavaScriptはAsm.jsで 型付け可能になり十分高速化されたが 中間言語バイナリ化することで データロード速度、コンパイル速度が向上した 現在は C++からコンパイルする必要がある

現状出来る事

C++で出来ることはだいたい出来るようです STL、pthread、OpenGLSDL・・・ などなど

今後追加予定

共有メモリを使った高度なスレッド ゼロコスト 例外処理 fixed-width SIMD GC/DOM などなど 新機能が追加予定のようです

現状でも色々できそう

次はWindowsでビルド環境つくるぞ

今度記事かくけど、Macやめましたので Windows10で環境構築しようとおもいます

http://webassembly.org/getting-started/developers-guide/

The instructions on this page are applicable to Linux and Mac OS X systems. Similar instructions for Windows systems are forthcoming.

公式ページでは LinuxMacでの手順はあるが、Windowsは また今度ね! とのことだが おそらくWindowsでも問題ないので 挑戦する!