ページ

2012年6月19日火曜日

[勉強会] VSUG DAY 2012 Summer(東京)に行ってきた

6/16 にマイクロソフトの品川オフィスで開催された VSUG DAY 2012 Summer に行って来ました。
当日早くに新幹線で移動して、ちょうど受付開始時間くらいに会場に到着。
すべてのセッションを聞かせて頂きましたが、Windows 8 に Visual Studio 2012、ASP.NET MVC と旬なものが盛り沢山といった感じでものすごくおもしろかったです。

私もセッションを担当させて頂きました。セッションで使った資料を下に貼り付けておきます。(そのうち VSUG のサイトにまとめて上げられるかもしれませんが)
そういや、デモをしようと VS2012 を立ち上げたときにメトロスタイルのデザイナーがエラーを表示して動かなかったのはちょっと焦りました。エラーメッセージを見ると 「解像度が 1024×768 を下回ってる」 となってて、原因がすぐにわかったので事なきを得ましたが。(プロジェクターに繋いだ時にいつの間にか 1024×600 とかになってて縦が 768 無かったのが原因)しかし、1024×768 無いとデザイナーすら立ち上がらないというのは知りませんでした。

終了後はいつものように懇親会に参加。
さらに二次会へと移動。実はこのあたりからあまり記憶がありません(汗)
その後、温泉に泊まり、お風呂の中で寝てしまったり、テーブルに突っ伏して寝てしまったりw
翌日はお台場のガンダム見てから新幹線で帰阪。

2012年6月16日土曜日

[勉強会] VSUG DAY 2012 Summer(東京) 6月16日開催!

今年も VSUG DAY 2012 Summer がマイクロソフトの品川オフィスをお借りして 6月16日に開催されます。
VSUG に会員登録さえしておけば参加は無料です。

今回は Windows 8、Visual Studio 11 といったところを中心としたセッションとなっています。
私もスピーカーをさせて頂きます。
(Windows Developer Days で 6月第1週に Windows 8 Release Preview がリリースされるとアナウンスされたので、それを使うつもりですが。。。ものすごく変わっていたらどうしようとちょっとビクビクしていたり)

VSUGDAY_2012_Summer_120×180.png

(この記事の日付を VSUG DAY が開催される日にしてあるので、それまで一番上に表示されます)

2012年6月14日木曜日

[Win8] 今さらですが Windows 8 Release Preview をインストール

今さらですが Windows 8 Release Preview をインストールしたのでその覚え書き。

インストール先 PC は MacBook Pro。(ちょうど今日新型の MacBook なんかが発表されてるようですが、もちろんそんなのではなく 1年くらい前の機種です)
Mac ではありますが、パーティション分けて Mac OS と Windows 7 が入っていて、その Windows 7 側に入れるので入れ方はごく普通の PC と同じです。

すでに入っている Windows 7 の環境を壊さないように VHD で入れることにしました。
VirtualPC や VirtualBox、VMWare などといった仮想マシンと違い、VHD は仮想ハードディスクです。すでに入ってる Windows 7 から見ると数十Gバイトあるでっかいファイルが一つ増えるだけです。パーティションを切り直したりなどややこしいことをする必要が無いので既存環境を壊す心配を(あまり)しなくてよくなります。かつ、仮想マシンだとそれなりにパフォーマンスが劣化しますが、VHD だとパーティションを分けてデュアルブートにしたのとほとんど変わらないためパフォーマンスの劣化はありません。(ハードディスクが仮想になっている分の影響はあるのかもしれませんが)

■ VHD に Windows 8 Release Preview をインストール

Windows 8 Release Preview を VHD にインストールする手順は
http://www.atmarkit.co.jp/fwin2k/win7/11vhdboot/11vhdboot_02.html
こちらの Windows 7 を VHD にインストールする手順と同じでした。
ざっと書いておくと

  1. まずは Windows 8 Release Preview の ISO イメージ をダウンロードして DVD なり USB メモリなどに焼く。(手元に手頃な USB メモリが無かったので DVD に焼きました)
  2. これを PC に入れてブート。(MacBook Pro の場合は Option キー押しながらブートして DVD を選択してやると “Press any key” とか何とか言われたので何かキーを押したらブートしてくれた)
  3. しばらく待っていると、最初のインストールする言語などを選ぶダイアログが出るのでここで Shift + F10 キーを押してコマンドプロンプトを立ち上げる。
    ここで以下のように入力。(太字が入力するところ)
    X:\Sources> diskpart
    DISKPART> create vdisk file=c:\VHD\Windows8RP.vhd type=fixed maximum=50000
    DISKPART> select vdisk file=c:\VHD\Windows8RP.vhd
    DISKPART> attach vdisk
    DISKPART> exit
    X:\Sources> exit
    これは、diskpart の create で C ドライブの VHD フォルダーに Windows8RP.vhd というファイル名でサイズ 50ギガバイトの仮想ハードディスクを作ってます。もちろん、ファイル名、サイズははなんでもいいです。おそらく Windows 8 Release Preview と Visual Studio 2012 を入れるくらいなら 30ギガくらいでも足りるんじゃないかと思いますが、やったこと無いので確実なところはわかりません。
    ちなみに、この create はそれなりに時間がかかります。50ギガだと 20~30分くらいかかったような。
    create が出来れば、あとは一瞬で終わります。
    仮想ハードディスクができたら exit してコマンドプロンプトを閉じます。
  4. インストールを進める。
    「今すぐインストール」 して、プロダクトキーを入力(プロダクトキーは ISO イメージのダウンロードサイトに書いてある)して、ライセンスに同意して、次のところでカスタムインストールを選択しインストール先を選ぶ。
    DiskPart で作った領域があるはずなのでそれを選択します。たとえば、「ドライブ 1 の割り当てられていない領域  48.8GB」 とかになっている。
  5. あとはそこにインストールしていけばいいはず。

ただ、私の MacBook Pro ではうまくいきませんでした。
上記の 4 のところで 「ドライブ 1 のパーティション 1 に Windows をインストールすることはできません」 とか言われちゃいます。詳細を表示してみると 「このディスクに Windows をインストールすることはできません。このコンピューターのハードウェアでは、このディスクでの起動がサポートされていない可能性があります」 とか何とか書かれてます。検索してみると MacBook に BootCamp 無しで Vista や Windows 7 を入れるときにも同じように言われるようです。で、解決策らしい解決策はみつかりませんでした。


■ 最初だけ VirtualBox を使って VHD に Windows 8 Release Preview をインストール

というわけで違う方法を。
使う方法は伊勢シンさんの 「インストールメディアを一切用意せずにWindows 8を物理ブートできるようにセットアップする方法」 こちらに書かれている方法まんまです。
こちらの記事はタイトルのとおり、DVD や USB メモリといったメディアが無いときに ISO ファイルだけでインストールする方法ですが、今回のように MacBook Pro で VHD を作ってもインストーラにはじかれちゃう時にも有効なようです。
伊勢シンさんの記事のままですが一応手順を書いておきます。

  1. 既存の Windows 7 に VirtualBox をダウンロードしてセットアップ。
  2. VirtualBox で Windows 8 の仮想マシンを作成。このとき、VHD には上で作った Windows8RP.vhd を指定する。(もちろん、伊勢シンさんの記事にあるように 「コンピューターの管理」 で VHD を作成してもいいと思います。ただ、以前に同じことをやったときに 「コンピューターの管理」 で作った VHD を VirtualBox が認識できなかったことがあります。どこかの設定を間違ってただけだと思いますが。VirtualBox にも VHD の新規作成がありますからそちらで作成すればもちろん VirtualBox に認識されます)
  3. 仮想マシンのストレージの CD/DVD に Windows 8 Release Preview の DVD を指定する。
  4. 仮想マシンを起動して Windows 8 Release Preview をセットアップ。
  5. 最初の再起動のところで仮想マシンを終了する。

伊勢シンさんのこの記事を最初に見たときはかなり驚いたんですが、こんなことができるんですね。
最初の再起動の時点までで起動に必要なものはひととおり VHD の中にコピー済みなわけです。なので、あとは VHD の中の OS をブートするようにしてやれば OK なんですね。
というわけで、まずはデュアルブートの選択ができるようにします。

  1. コマンドプロンプトを 「管理者として実行」 で立ち上げる。
    ここで以下のように入力。
    C:\> BCDEDIT /copy {current} /d "Windows 8 Release Preview"
        (ここで表示される {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx} を以下にコピーする)
    C:\> BCDEDIT /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx} device vhd=[C:]\VHD\Windows8RP.vhd
    C:\> BCDEDIT /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx} osdevice vhd=[C:]\VHD\Windows8RP.vhd

続いてブートローダーを置き換えます。(Windows 7 のブートローダーでは Windows 8 を起動することが出来ないそうです)

  1. Windows 8 のインストールメディアのルートにある bootmgr を C:\bootmgr_new フォルダーにコピーする。
  2. マシンを再起動。
  3. 上の BCDEDIT の設定がうまくできていれば、Windows 7 と Windows 8 Release Preview を選択する画面が出るはず。ここで Windows 7 の上で F8 を押してオプションに入り、「コンピューターの修復」 でログインしてシステム回復オプションを表示し、コマンドプロンプトを起動する。
    この回復オプションのコマンドプロンプトで以下のように入力。
    C:\> ATTRIB –R –S –H C:\bootmgr
    C:\> REN C:\bootmgr C:\bootmgr.bak
    C:\> COPY C:\bootmgr_new\bootmgr C:\
    C:\> ATTRIB +R +S +H C:\bootmgr
    (ようするに Windows 8 Release Preview の DVD に入っている bootmgr を C ドライブのルートにコピーするってことです)
  4. 再びマシンを再起動。
  5. 今度は Windows 8 Release Preview の方を選択して起動すれば Windows 8 のセットアップの続きが始まるはず。

これで Windows 8 Release Preview が VHD にインストールできました。
ちなみに、コントロールパネルの 「システム」 の 「システムの詳細設定」-「起動と回復」 でブート時にデフォルトで選択する OS を指定できます。


■ Microsoft アカウントへの切り替え

いきなり Microsoft アカウントでユーザーを作成すると C:\Users\%USERNAME% のところが Microsoft アカウントでの名前(live.com 上で登録する名前)になるようです。なので、ここに日本語(全角文字)を使ってると C:\Users\%USERNAME% も日本語(全角文字)になっちゃってとても気持ち悪いことになります。

今回、私がインストールしたときはローカルアカウントしか聞かれませんでしたが、以前 Developer Preview を入れたときは最初に Microsoft アカウントを聞かれて、そのときは確かに C:\Users\青柳臣一 とかってなってたように思います。

これは、

  1. インストール時は Microsoft アカウントでは無くローカルアカウントで入れる。
  2. インストール後に 「PC 設定」 の 「ユーザー」-「Microsoft アカウントへの切り替え」 で Microsoft アカウントに切り替える。

こうすると C:\Users\%USERNAME% のところは 1 で入力したユーザー名のものがそのまま使われるようです。
(こうすればいいとどこかで読んだのですが、どこで読んだのかわすれちゃいました)


■ BootCamp のドライバーをインストール

上記の方法で Windows 8 Release Preview を入れてみたところ、無線LAN、サウンド、カメラといった標準装備のデバイスが全然認識できてませんでした。(Consumer Preview のころも同じでしたが)
Mac 側で BootCamp のドライバーを DVD に作って、これを使ってドライバーを入れようとしました。しかし、セットアップを起動すると 「Windows 7 では無い」 と言われてセットアップできません。「互換性」 で Windows 7 にしても状況は変わらず、どうしようもありませんでした。

で、ちょっとまともな方法とは言えないかもしれませんが、以下の方法で対応。

BootCamp のドライバーディスクの Drivers フォルダーの下にある XxxxInstaller とか XxxxSetup とかの実行ファイルを片っ端から実行しました。32 とか 64 とか付いてるものは(今回は Windows 8 64bit なので) 64 の方を、付いていないものはとりあえず起動してみるという感じ。どうやら大元の setup.exe は Windows 7 かどうかをチェックしていますが、個別のインストーラーは特にチェックしていない様子。Drivers フォルダーの下をたどって、インストーラーらしいものを片っ端から実行してやると無線LAN、サウンド、カメラといったデバイスが一通り認識されるようになりました。

あと、これは MacBook だからかどうかわかりませんが、ディスプレイの輝度が明るくなったり暗くなったりどうもおかしいです。これは、「PC 設定」 の 「全般」-「画面」-「画面の明るさを自動的に調整する」 をオフにして手動で固定値にしてやりました。


■ Visual Studio 2010 や Windows Phone 7.1 SDK を入れる

使うこともあるかと Visual C# 2010 Express や Windows Phone 7.1 SDK を入れました。これらは Visual Studio 2012 と共存できます。もちろん、必要ない人は入れる必要はありません。

VS2010 は何も問題なく入りました。もちろん、VS2010 SP1 も問題なく当たりました。(というか SP1 を当てておかないと Windows Phone 7.1 SDK が入りません)

Windows Phone 7.1 SDK を Windows 8 Release Preview に入れるときは以下の手順が必要な必要です。
Windows Phone SDK 7.1.1をWindows 8 Release Previewへインストールする際の注意点


■ ブート時の OS の選択を消す

インストールとは関係無いですが、bcdedit で余計なエントリーを消す方法。

  1. コマンドプロンプトを 「管理者として実行」 で起動する。
    ここで、
    C:\> BCDEDIT
        ここに一覧が表示されるので消したいエントリーの identifier (GUID)を控える

    C:\> BCDEDIT /delete {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}

■ ディスクの使用容量は?

途中でディスクの使用容量見てなかったんですが、

  • Windows 8 Release Preview
  • Microsoft Office 2010 Standard
  • Visual C# 2010 Express
  • Windows Phone 7.1.1 SDK
  • Visual Studio 2012 Ultimate

とこれだけ入れると 30.7ギガバイトでした。

2012年6月7日木曜日

[WP7] Lumia 800 を 105,000フィートまで飛ばしてみた

University of Southampton sends a Nokia Lumia 800 to 105,000 feet」 より。
こちらは Microsoft UK Education チームのブログですが、Southampton 大学が ASTRA(Atmospheric Science Through Robotic Aircraft : ロボット機による大気研究、という感じかな)の一環として Windows Phone 7.5 搭載の Nokia Lumia 800 を 105,000フィートまで飛ばしてみたということが紹介されています。
記事やリンク先には上空から撮影した美しい写真がいくつか紹介されています。(もちろん、Lumia 800 で撮影したものなんでしょうね)

大気調査用の風船に Lumia 800 を付けて飛ばし、高度 105,000フィート(32km)まで上がり、そこは –61C の世界だそうです。
データは Windows Azure で処理しているそうですが、どうやら高度 8km までは 3G で接続できていたということみたいです。図に高度 23km でパワーダウンとありますね。解説は見つかりませんが、低温すぎて機能不全をおこしちゃったのかな?けど、GPS やジャイロ搭載で通信機能まである安価な機器ってことで、観測用風船の軌道調査などに役立ちそうだってことみたいです。
確かに考えてみりゃ、GPS やジャイロ、カメラ、3G、WiFi といった機器を装備していて、かつ、無料の開発環境(Visual Studio)でアプリを作れるデバイスが数万円程度で手に入るんですからねぇ。

2012年6月1日金曜日

[VS2012] async/await のパフォーマンスの注意点

前の記事 で紹介した 「What’s New for Parallelism in Visual Studio 2012 RC」 の補足記事が来てました。

Performance consideration for Async/Await and MarshalByRefObject
これ、個人的にはものすごく重要なことのような気ガス

前の記事にあった StreamReader.ReadLineAsync メソッドが 3倍速くなったとかはどういうことなのか?
詳しくは上の記事を読んでもらった方がいいと思いますが、ざっくりと説明します。
上記の記事からコードの重要な部分をコピペします。

class MyObj 
{ 
    const int ITERS = 100000000; 
    private int m_data; 

    public async Task Foo1() 
    { 
        for (int i = 0; i < ITERS; i++) m_data++; 
    } 

    public async Task Foo2() 
    { 
        int localData = m_data; 
        for (int i = 0; i < ITERS; i++) localData++; 
        m_data = localData; 
    } 
}

この Foo1 メソッドと Foo2 メソッドの実行速度を調べると Foo1 の方が 3倍くらい遅いそうです。
なぜか?
async なメソッドはコンパイラによって中身がゴニョゴニョされて await が使用できるようなコードに変換されます。(メソッドの中身が IAsyncStateMachine を継承した別クラスに切りだされて、await ごとに状態遷移するようなステートマシンなコードになる) コード上では単なるフィールドへのアクセス(m_data へのアクセス)に見えますが、コンパイル結果は単なるアクセスじゃなくなっているわけです。そのため、その分遅くなってしまうということだそうです。

さらに

class MyObj

class MyObj : MarshalByRefObject

とすると差が大きくなります。
実に Foo1 は Foo2 の 72倍くらい遅くなってしまいます。Foo2 の方は MarshalByRefObject であっても無くてもほとんど速度は変わりません。
これは、どうやら以下の理由だそうです。
MarshalByRefObject を継承したクラスはリモートアクセスが可能になります。リモートアクセスする場合はプロキシーが生成され引数などがマーシャリングされて渡されるわけですが、これはかなり重い処理です。なので無駄にプロキシー経由にならないようになっています。プロキシーが必要かどうかは 「別 AppDomain かどうか」 で判断します。しかし、この判断自体もオーバーヘッドになってしまいます。なので、JIT は自分自身(すなわち “this”)にアクセスする場合は絶対に同じ AppDomain だとしてチェックを省略し、普通にローカルなフィールドにアクセスするのと同じ速度になるようにしています。
ところが、async なメソッドになると上に書いたようにメソッドの中身が別クラスに切り出されるため m_data へのアクセスは this へのアクセスではなくなります。そのため m_data にアクセスするたびに 「同じ AppDomain かどうかのチェック」 をしなくちゃいけなくなります。これがオーバーヘッドになって 72倍という速度差になります。(ちなみに、もし別 AppDomain になって、プロキシー経由のアクセスになると数百倍くらいの速度差にはなるんじゃないかと思います。COM のころはそんな感じでした)
ちなみに、Stream や TextReader、TextWriter といったクラスは MarshalByRefObject から派生しています。

これはプロパティにするとちょっとましになるそうです。

private int Data { get { return m_data; } set { m_data = value; } } 

public async Task Foo3() 
{ 
    for (int i = 0; i < ITERS; i++) Data++; 
}

意味的には Foo1 とまったく同じですが、JIT が最適化するヒントになって Foo3 は Foo2 に比べて 10倍くらい遅い(Foo1 に比べて6倍ちょっと速い)となるそうです。

まぁ、こうしても遅くなるのは確かなので結局のところ 「async なメソッドでは極力フィールドやプロパティにアクセスせず、可能な限りローカル変数アクセスになるようにする」 ということになりそうです。
別の意味でもなるべくローカル変数になるようにした方が安全です。
async なメソッドで await を使うと非同期で動くようになるわけですからそこからフィールドやプロパティにアクセスするときは排他を考えてやらなくちゃいけません。async/await を使うとあまりにお手軽に非同期できちゃうので忘れがちになってしまいますが、非同期で動いている以上、外部のリソースにアクセスする場合は常に 「別の非同期メソッドとの読み書きがバッティングして内容が破壊されるようなことは無いか」 を考えてやらなくちゃいけません。ローカル変数は外部ではありませんので、そういったややこしいことを考える必要が無くなります。(注意: 別のクラスのインスタンスをローカル変数に持っていて、そのインスタンスが別の非同期メソッドからアクセスされるような場合は当然ちゃんと考えてやらなくちゃいけません。ローカル変数ならなんでも大丈夫ってわけじゃありませんのでご注意を)

[VS2012] Visual Studio 2012 RC での変更点

What’s New for Parallelism in Visual Studio 2012 RC」 より。
Visual Studio 2012 RC での変更点がまとめられてました。

コンパイル時に async なメソッドには AsyncStateMachineAttribute がつけられるようになったそうです。コード解析するツールとかで async なメソッドであったことがわかるようにってことらしいです。

async/await キーワードに関しては(中身が)いろいろ変わった模様。
いろいろ改良されて、async/await 時に消費されるメモリも、オーバーヘッドもかなり減ったとのこと。
また、ベースクラスライブラリ(BCL)の Async なメソッド自体も改良されているそうです。たとえば、StreamReader.ReadLineAsync メソッドは 300% くらい速くなってるとか。他にも BufferedStream 類もいろいろ改良したとか、AsStream や AsStreamForRead なんかは BufferedStream を使うようにしたとか、非同期関連はコンパイラ・ライブラリ通していろいろと改良されているようです。

ASP.NET も Beta まではイベントハンドラに async 付けるとバギーだった(代わりに RegisterAsyncTask を使う)のが、どうやら async 付けても大丈夫になった模様。
他にも HttpRequest、HttpResponse でキャンセル可能になったとかいくつかの改良がされているようです。

Dataflow (System.Threading.Tasks.Dataflow)がなくなっちゃいました。
どうやら、Beta まではフル .NET Framework のパッケージに入ってたけどメトロスタイルには無いとかそういう状況だったけど、デスクトップとメトロスタイルの両方で使えるように .NET Framework からは分離して NuGet で提供するようにしたってことみたいです。
詳細は 「MEF and TPL Dataflow NuGet Packages for .NET Framework 4.5 RC [Nick]」 にあります。
System.Threading.Tasks.Dataflow.dll は無くなって Microsoft.Tpl.Dataflow として NuGet にある。これはデスクトップ、サーバー、メトロスタイルのすべてをサポートする。なお、まだ Prerelease なので “Include Prerelease” にしておかないと一覧で出てこない模様。
あと、MEF も Beta のころはメトロスタイルでは .NET Framework 版 MEF のサブセットが使えるという感じだったが、これからは MEF for Metrostyle という新しいパッケージとして NuGet で取得できるようになってるそうです。