K.Sasada's Home Page

Diary - 2014 June

研究日記

水無月

_20(Fri)

最近、コードを書くとき、keyword 引数を使うようになってきたんだけど、

def foo(a: true)
  do_something if a
end

foo(a: false)

のつもりで、

def foo(a = true)
  do_something if a
end

と書いてしまって、foo(a: false) とやっても a は Hash object {a: false} になってしまい、偽にならなくて困ったという話。なんとなく動いちゃってるから、よくわからなかったという。

オプショナル引数禁止、とかできるといいのかもしれないな。

_18(Wed)

仮想マシン上で TSC (time stamp counter) がどうなるか、という話。

てっきり、CPU の物理 TSC が返るのかと思ったら、ちゃんと VT-x では trap するようになっているようで。

#if defined(__GNUC__) && defined(__i386__)
typedef unsigned long long tick_t;

static inline tick_t
tick(void)
{
    unsigned long long int x;
    __asm__ __volatile__ ("rdtsc" : "=A" (x));
    return x;
}

#elif defined(__GNUC__) && defined(__x86_64__)
typedef unsigned long long tick_t;

static __inline__ tick_t
tick(void)
{
    unsigned long hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ((unsigned long long)lo)|( ((unsigned long long)hi)<<32);
}

#elif defined(_WIN32) && defined(_MSC_VER)
#include <intrin.h>
typedef unsigned __int64 tick_t;

static tick_t
tick(void)
{
    return __rdtsc();
}

#else /* use clock */
typedef clock_t tick_t;
static inline tick_t
tick(void)
{
    return clock();
}
#endif

int main()
{
    volatile int n = 0x100000;
    int i;

    for (i=0; i<n; i++) {
	tick();
    }
}

#if 0
$ gcc -O0 rdtsc.c && time ./a.out

仮想マシン(VirtualBox on Windows):
real    0m1.744s
user    0m1.740s
sys     0m0.000s

同じマシンでのVC:
real    0m0.049s
user    0m0.000s
sys     0m0.015s

別の実機(Debian/Squeeze):
real    0m0.039s
user    0m0.040s
sys     0m0.000s
#endif

明らかに結果が違う。

Stack overflow で、Why is RDTSC a virtualized instruction on modern processors? では、同じような質問をされているんだけど、accuracy が重要なんだよ、とか、そういう話。

side-channel attack というか、VM 上で動いているかどうかの判定に使われないようにする、っていうのも、結局 rdtsc が 30 倍程度遅くなることがわかってしまうので、無理なんじゃないかなぁ。

offsetting を VM-exitting ごとに適切に再設定すれば、RDTSC 命令自体は、CPU 1 命令で済むのかと思ったけど、offsetting の仕様を適切に理解できていない気もする。


元々、clock_gettime() がえらい遅い、ということで調べ始めたのだけど。VM 上の時間取得は大変(鬼門)だなぁ。準仮想化のターゲットにしないのかしら(ホスト側の設定値がそのまま見える、的な)。

Sasada Koichi / ko1 at atdot dot net
$Date: 2003/04/28 10:27:51 $