hagio.org - 日記

Powered by PENS


Index

2009: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2010: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2011: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2012: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2013: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2014: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2015: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2016: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)(2)
2017: 1月(1)(2) 2月(1)(2) 3月(1)(2) 4月(1)(2) 5月(1)(2) 6月(1)(2) 7月(1)(2) 8月(1)(2) 9月(1)(2) 10月(1)(2) 11月(1)(2) 12月(1)

今月のアルバム [ 投稿 | 編集 ]


編集

April 2009

Apr 23 (Thu)

23:39

ところで、32 ビット OS でも long long int で 8 バイトの整数が定義できるが、 これはどのように処理されているのだろうか?気になってので実験してみた。

[hagio@lab ~]$ cat > 64bit.c int main(void) { long long int s64, r64; s64 = 0x1000000000000000LL; r64 = s64 + 1; return 0; }

これのアセンブリコードが以下。

[hagio@lab ~]$ cc -S 64bit.c [hagio@lab ~]$ cat 64bit.s .file "64bit.c" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $20, %esp ★movl $0, -24(%ebp) ★movl $268435456, -20(%ebp) movl -24(%ebp), %eax movl -20(%ebp), %edx ☆addl $1, %eax ☆adcl $0, %edx movl %eax, -16(%ebp) movl %edx, -12(%ebp) movl $0, %eax addl $20, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.1.2 20071124 (Red Hat 4.1.2-42)" .section .note.GNU-stack,"",@progbits

おもろい。単に 4 バイトずつ 2 回に分けて計算しているだけのようだ。 ただ、下位 4 バイトは下位 4 バイト同士普通に加算しているが、上位 4 バイトはキャリー付きの加算を行っている。 つまり、下位 4 バイトの加算結果があふれたら、上位 4 バイトに 1 を足す。 これにより、2 回に分けても上手く計算できるようになっている。 おもろい!! 乗算などの他の計算だとどうなるか… すでにやってみたのは言うまでもない。

その昔、Apple が「PowerPC G5 は 64 ビットだから速いぜ!」みたいな売り方をしていたが、 ようやくその意味がわかった気がする…。

ちなみに、Mac (Leopard) は 64 ビットアプリもコンパイル&実行可能だ。 gcc を -m64 オプション付きで叩けばよい。

$ gcc -m64 -S 64bit.c $ cat 64bit.s : LCFI1: movl $0, -16(%rbp) movl $268435456, -12(%rbp) movq -16(%rbp), %rax incq %rax movq %rax, -8(%rbp) movl $0, %eax leave ret :

出ましたよ RAX、スーパーリッチ (性能的な意味で)。

20:00

最近まで、「メモリは多ければ多いほど良い」と信じ切っていたのだが、状況によってはそうではないことを知って驚愕した。

x86 版 Linux カーネルの場合、いくらメモリを積んでも、カーネルが利用できるメモリ領域は最大で 1 GB 程度に制限されている。 メモリを増設すると、「メモリを管理するためのメモリ領域」が増大するため、その分カーネルが利用できるメモリ領域が圧迫されてしまう。 それぞれのプロセスがいくら大量のメモリを利用できても、カーネルのメモリが無くなってしまえばシステムとしてはおしまいなわけで、 そうさせまいとメモリ回収処理が走りまくって遅くなったり、ひどい場合はプロセスを強制的に落としてしまったりする… ということらしい。

まあ、一般的に使うレベルだとここまで極端なことにはならないだろうけど (増設のレベルも 4 GB とかその程度なので)、 メモリが多いことはいいことだ!と信じて疑わなかったオレにとって、この事実はまさに目から鱗。 本質を理解していないとこういうことがある… といういい教訓になった。

Apr 22 (Wed)

01:27

1984 年生まれのオレとしては、いつも以上に気になる最新作。できれば GW 前に発売して欲しかったな。

Apr 20 (Mon)

12:55

ドリップタイプのコーヒーの袋を開けた瞬間、 香りが良すぎて昇天しそうになるのはオレだけではあるまい。

4 月(1) へ


↑戻る