目次: Java
Javaのhprofというプロファイラは、準備を必要とせず(JDK標準だから)に、CPU、ヒープ、モニタの衝突など、一通り測れる便利なプロファイラです。
特に各メソッドのカウントを「全て取る」モード(-Xrunhprof:cpu=times)は、明らかに呼び過ぎのメソッドが一発で分かるため、大変に便利です。
しかし便利な反面、実行速度が下がりすぎて使い物にならなくなる場合があります。
今日遭遇したケースは、7MBのファイルをDataInputStreamからreadByte() するプログラムです。通常のデバッグ実行であれば、ほんの一瞬で終わりますが、cpu=timesでプロファイリングすると10分経っても終わりません…。
どうも、細かいメソッドが頻繁に呼ばれすぎるせいで、メソッド呼び出しのカウントを行う部分がパンクしているようです。
思い出してみればInputStream系はInputStream -> BufferedInputStream -> DataInputStreamなどのように連鎖させるのでメソッド呼び出しが深く、データをロードするという処理はループ回数が多くなりがちなので、深さ×ループ回数の掛け算に比例してどんどん遅くなってしまいます。
これはよろしくありません。
待てるくらいの時間に収まるように、何とか軽くしてみましょう。
まず目を付けたのはreadByte() です。readByte() で1バイトつずつ読むから呼び出しカウントが多くなるわけです。ならばreadLong() で8バイトずつ読めばカウントは1/8です。
コードもちょい変えで済むし、お手軽高速化としては、プロファイリング時の実行速度もほぼ8倍になる、という中々の効果です。
しかしreadLong() を持ってしても100MBオーバーとなると厳しいでしょう。もし本当にそこまで必要なら、根底から覆す(InputStreamを使わないとか)別の手立てを考える必要がありそうです。
この記事にコメントする
私のスマホは防水だけど、その意味は雨でも壊れない、であって、雨でも使える、って意味ではないんだなあ。
なぜなら、タッチパネルに水滴が着くとまともに動かないからです…。
メモ: 技術系の話はFacebookから転記しておくことにした。
この記事にコメントする
ARMアーキテクチャを表すときARMv5Tがあって、ARMv6Tがないのはなぜでしょう?
ARMv5TのTの部分は「バリアント」と呼ばれ、TバリアントであればTHUMB命令セットに対応したARMアーキテクチャである、ことを示します。他にもエンハンストDSP命令のEとか、Jazzele命令のJがあります。
ARMv5まではTHUMB命令セットへの対応はオプションでした。このため、ARMv5世代のARMアーキテクチャはTHUMB非対応のARMv5とTHUMB対応のARMv5Tの2種類が存在し得ました。実際にTHUMB未対応のARMv5プロセッサを作った会社があるか、まではわかりませんが。そういうプロセッサを「作っても良い」ことにはなっていました。
例えば、携帯でよく使われていたARM926EJ-SプロセッサのアーキテクチャはARMv5TEJ、つまりTHUMBとエンハンストDSPとJazzeleに対応したアーキテクチャ、という意味です。
しかしARMv6からはTHUMB対応が必須となり、THUMBの有り/無しを区別する必要がなくなり、名前もARMv6のみとなりました。ARMv6はTHUMB命令セットに対応していてもARMv6Tとは呼びません。対応している機能を全部並べ始めると、冗長になるためでしょう、たぶん。
なお、エンハンストDSP命令もv6でARM命令セットに取り込まれたため、Tと同時にEバリアントも消滅しています。
さらに、最近のARMv7アーキテクチャでは、バリアントの考えが変わったようで、ARMv7の後ろに対応機能を意味するアルファベットは付かなくなりました。
種類もARMv7-AとARMv7-RとARMv7-Mの3つです。それぞれ「アプリケーション」「リアルタイム」「マイクロコントローラ」プロファイルの意味だそうです。対応する機能は下記の通り。
アーキテクチャが対応する命令セットの規模順に並べたとき、ARMとなるところもまたニクいですね。イギリス人はこういうシャレが好きなのでしょうか?
これ以上の詳細情報はARMのサイト(ARMのサイトへのリンクを張っておきます)をご覧ください。
余談ですが、ARM命令セットやTHUMB命令セットにもバージョンがあります。下記の通りです。
バージョンは1:1に対応しており、異なる世代を組み合わせること、たとえばARMv6とTHUMBv2を組み合わせることはできません。
メモ: 技術系?の話はFacebookから転記しておくことにした。なおARMv7の節は8/25に加筆。
この記事にコメントする
目次: PC
一昨年買った(2012年4月5日の日記参照)、Logicool Perfomance MX M950が壊れました。マウスの左ボタンがバカになって、全部ダブルクリックになってしまう、良くある壊れ方です。
形あるもの、いつか壊れるとは思っていますが、1万以上したマウスが2年で壊れるのはちょっと悲しい。
存外に早く壊れた以外、使い勝手は最高に気に入っていたので、もう一個M950を買いました。アマゾンで8,226円でした。前回は12,000円したので、3割近く安くなっていますね。
しかし2年前のフラッグシップモデルだったM950が、未だにフラッグシップモデルとして君臨しているのはちょっと意外でした。余程の人気なのか、それとも新製品開発をあまりしていないのでしょうか。
Logicoolマウス愛好者としては、後者でないことを祈るばかりです。
新たにやってきたM950の保証書を見てびっくり。保証期間「ご購入日から3年間」の文字が輝いています。
さ、3年…だと…?ということは、壊れたマウスは保証期間内?無料で直せちゃう感じ?マジで…?
普通のメーカー保証は1年で速攻切れる役立たずなイメージですが、3年ってすごいですね。さすがだなLogicoolさん。でも、もう保証書がどっか行ってしまったから、何年でも意味なかったりするのだけど…。今度は大事に取っておきます。
この記事にコメントする
CentOS7 EXT4 vs XFS vs Btrfs vs ZFS on vda - Qiita を読んで。
参考になります(※1)。ZFSはFUSE経由じゃないNative実装があるのか…知らなんだ。
(※1)補足。この手のベンチマークはたくさんあるように見えて、ファイルシステム側の進化が早いため、すぐに陳腐化します。なので、新しいベンチマークは常にありがたいものです。
XFSは1MB overのデカいファイルは速いけど、1KBくらいの細かいファイルのcreate/deleteをぶちかます(カーネルのtarballを展開しながら、古いカーネルソースをrm -rするとか)と、すっごい遅くて嫌になって使うの辞めた記憶があるのだけど…改善されたのだろうか?
メモ: 技術系?の話はFacebookから転記(※2)しておくことにした。
(※2)本来8月14日のエントリです。8月14日辺りでエミュレータが動いたのが嬉しくて、浮かれてFacebookに書きまくったら、このサイトに転記しきれなくなったため、未来のエントリに移動させています。
この記事にコメントする
目次: C言語とlibc
switch文を使ってはいけないを読んで。
PHPはさておいて。私もswitchよりStateパターンを選びますが、C言語の関数ポインタでStateパターンを実現するのは、今も迷います。言語仕様上、悪い方に倒れるのを阻止できないためです。
ハッカーが明確で読みやすいコードを書いてくれるうちは良いですが、頭のおかしい人がdoという関数ポインタに全関数を入れるクソコードを書き始めたらもう全部パアです。
いやまさかそんなこと、と思うかもしれませんが、どこの会社とは言いませんがそんなクソコードが実在してるんですよ、世の中って怖いですよね…。
この記事(コードのネストを深くするな)を読んでいたら、会社のクソコード山脈を思い出しました。
7段ifなんて序の口。世の中の悪手とされる書き方は、大概やってるワルい奴です。バグも多い…。
メモ: 技術系?の話はFacebookから転記(※)しておくことにした。
(※)本来8月14日のエントリです。8月14日辺りでエミュレータが動いたのが嬉しくて、浮かれてFacebookに書きまくったら、このサイトに転記しきれなくなったため、未来のエントリに移動させています。
この記事にコメントする
【レビュー】超小型PC「Raspberry Pi」で夏休み自由課題・第1回 - Raspberry Piとは? 入手とセットアップ (1) Raspberry Piでコンピューターを学ぼう を読んで。
"Raspberry Piは少々とっつきにくい。買ってくると基板が入っているだけで、電源をつないでも動かないのだ。"(引用)
え!そうなの?
SDカードにtarball一個解凍するだけで使えるようになるので、一番とっつきやすい部類だと思ってました。
いつの間にか一般的な理解と乖離していたみたいです。うーん、認識を改めなければいかんなー…。
メモ: 技術系?の話はFacebookから転記(※)しておくことにした。
(※)本来8月13日のエントリです。8月14日辺りでエミュレータが動いたのが嬉しくて、浮かれてFacebookに書きまくったら、このサイトに転記しきれなくなったため、未来のエントリに移動させています。
この記事にコメントする
基本的には、コードを読むときに、覚えておかなければならないことを減らし、覚える時間を短く済ませた方がわかりやすい、と感じます。
覚えきれない量の条件や変数が出てくるコード、長時間覚えておかなければ理解できないコードは、どこかが病気だと思って、直すようにしています。
この記事にコメントする
目次: Linux
自作ARMエミュレータでLinux 3.12.26をブートし、Busyboxのashのプロンプト表示まで到達しました。
現時点での動作イメージです。実際は最初の方にエミュレータのデバッグメッセージが大量に出ますが、意味ないので叩き切ってます。
Connected to the target VM, address: '127.0.0.1:49281', transport: 'socket' Exception: Reset by 'Init.'. [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 3.12.26+ (katsuhiro@falcon) (gcc version 4.9.1 20140710 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.07 - Linaro GCC 4.9-2014.07) ) #1 Thu Aug 14 02:42:16 JST 2014 [ 0.000000] CPU: ARM926EJ-S [41069260] revision 0 (ARMv5TEJ), cr=00003137 [ 0.000000] CPU: VIVT data cache, VIVT instruction cache [ 0.000000] Machine: ARM-Versatile PB [ 0.000000] Ignoring unrecognised tag 0x00000000 [ 0.000000] Memory policy: ECC disabled, Data cache writeback [ 0.000000] On node 0 totalpages: 16384 [ 0.000000] free_area_init_node: node 0, pgdat c03ac754, node_mem_map c03c9000 [ 0.000000] Normal zone: 128 pages used for memmap [ 0.000000] Normal zone: 0 pages reserved [ 0.000000] Normal zone: 16384 pages, LIFO batch:3 [ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms [ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [ 0.000000] pcpu-alloc: [0] 0 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 [ 0.000000] Kernel command line: console=ttyAMA0 mem=64M lpj=0 root=/dev/ram init=/bin/sh debug printk.time=1 [ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes) [ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) [ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.000000] Memory: 59960K/65536K available (2742K kernel code, 155K rwdata, 712K rodata, 114K init, 111K bss, 5576K reserved) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) [ 0.000000] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB) [ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB) [ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB) [ 0.000000] .text : 0xc0008000 - 0xc0367c14 (3456 kB) [ 0.000000] .init : 0xc0368000 - 0xc03849fc ( 115 kB) [ 0.000000] .data : 0xc0386000 - 0xc03ace80 ( 156 kB) [ 0.000000] .bss : 0xc03ace80 - 0xc03c8d64 ( 112 kB) [ 0.000000] NR_IRQS:224 [ 0.000000] VIC @f1140000: id 0x00041190, vendor 0x41 [ 0.000000] FPGA IRQ chip 0 "SIC" @ f1003000, 13 irqs [ 0.000000] Console: colour dummy device 80x30 [ 1.823423] Calibrating delay loop... 0.51 BogoMIPS (lpj=2559) [ 2.008160] pid_max: default: 32768 minimum: 301 [ 2.051389] Mount-cache hash table entries: 512 [ 2.282632] CPU: Testing write buffer coherency: ok [ 2.336914] Setting up static identity map for 0xc029c520 - 0xc029c578 [ 3.015733] VFP support v0.3: no double precision support [ 3.115064] NET: Registered protocol family 16 [ 3.402544] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 4.241363] Serial: AMBA PL011 UART driver [ 4.264723] dev:f1: ttyAMA0 at MMIO 0x101f1000 (irq = 44, base_baud = 0) is a PL011 rev1 [ 4.657293] console [ttyAMA0] enabled [ 4.748693] dev:f2: ttyAMA1 at MMIO 0x101f2000 (irq = 45, base_baud = 0) is a PL011 rev1 [ 4.827661] dev:f3: ttyAMA2 at MMIO 0x101f3000 (irq = 46, base_baud = 0) is a PL011 rev1 [ 4.958784] fpga:09: ttyAMA3 at MMIO 0x10009000 (irq = 70, base_baud = 0) is a PL011 rev1 [ 6.984675] bio: create slab <bio-0> at 0 [ 7.563484] Switched to clocksource timer3 [ 10.489897] NET: Registered protocol family 2 [ 10.731930] TCP established hash table entries: 512 (order: 0, 4096 bytes) [ 10.761376] TCP bind hash table entries: 512 (order: -1, 2048 bytes) [ 10.781356] TCP: Hash tables configured (established 512 bind 512) [ 10.810155] TCP: reno registered [ 10.817472] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 10.833676] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 10.936594] NET: Registered protocol family 1 [ 11.031626] RPC: Registered named UNIX socket transport module. [ 11.039086] RPC: Registered udp transport module. [ 11.045485] RPC: Registered tcp transport module. [ 11.050589] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 11.116524] Trying to unpack rootfs image as initramfs... [ 107.483588] Freeing initrd memory: 1084K (c0800000 - c090f000) [ 107.546930] NetWinder Floating Point Emulator V0.97 (double precision) [ 107.961293] Installing knfsd (copyright (C) 1996 okir@monad.swb.de). [ 108.022282] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc. [ 108.128699] ROMFS MTD (C) 2007 Red Hat, Inc. [ 108.143263] msgmni has been set to 119 [ 108.269578] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) [ 108.280765] io scheduler noop registered [ 108.289606] io scheduler deadline registered [ 108.308715] io scheduler cfq registered (default) [ 108.386028] clcd-pl11x dev:20: PL110 rev0 at 0x10120000 SYS_CLCD: read 0x00001f00 LCDControl: 0x00000000 [ 109.004790] clcd-pl11x dev:20: Versatile hardware, VGA display SYS_CLCD: read 0x00001f00 SYS_CLCD: 0x00001f00 LCDIMSC: read 0x00000000 LCDTiming0: 0x27175f9c LCDTiming1: 0x200b05df LCDTiming2: 0x067f3800 LCDTiming3: 0x00000000 LCDUPBASE: 0x83000000 LCDLPBASE: 0x8304b000 SYS_OSC4: read 0x00000000 SYS_LOCK: 0x0000a05f SYS_OSC4: 0x0001c863 SYS_LOCK: 0x00000000 LCDIMSC: 0x00001029 LCDIMSC: 0x00001829 SYS_CLCD: read 0x00001f00 SYS_CLCD: 0x00001f03 SYS_CLCD: 0x00001f17 [ 113.628628] Console: switching to colour frame buffer device 80x60 [ 122.764467] brd: module loaded [ 122.953158] physmap platform flash device: 04000000 at 34000000 [ 123.244156] physmap-flash physmap-flash.0: map_probe failed [ 123.531512] smc91x: not found (-19). [ 123.686616] mousedev: PS/2 mouse device common for all mice [ 124.249155] TCP: cubic registered [ 124.257574] NET: Registered protocol family 17 UARTIFLS: 0x00000012 UARTFBRD: 0x00000000 UARTIBRD: 0x00000001 UARTLCR_H: 0x00000000 UARTFBRD: 0x00000004 UARTIBRD: 0x00000027 UARTLCR_H: 0x00000070 [ 124.810528] Freeing unused kernel memory: 112K (c0368000 - c0384000) ----- ls -la total 4 drwxr-xr-x 11 1000 1003 0 Aug 14 2014[1;34m.[0m drwxr-xr-x 11 1000 1003 0 Aug 14 2014[1;34m..[0m drwxr-xr-x 2 1000 1003 0 Aug 13 2014[1;34mbin[0m drwxr-xr-x 2 1000 1003 0 Aug 13 2014[1;34mdev[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34metc[0m -rwxr-xr-x 1 1000 1003 129 Aug 14 2014[1;32minit[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34mlib[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34mproc[0m drwx------ 2 0 0 0 Aug 13 2014[1;34mroot[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34mrun[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34msbin[0m drwxr-xr-x 2 1000 1003 0 Aug 8 2014[1;34msys[0m /bin/sh: can't access tty; job control turned off UARTFBRD: 0x00000004 UARTIBRD: 0x00000027 UARTLCR_H: 0x00000070 / # Disconnected from the target VM, address: '127.0.0.1:49281', transport: 'socket' Process finished with exit code -1 (メモ: コマンドラインから実行) $ java -cp out/production/semu net.katsuster.semu.Main ~/share/arm_cross/linux-3.12.26/arch/arm/boot/Image ~/share/arm_cross/work/initramfs.gz
エミュレータの出しているデバッグメッセージがなかったら、普通の起動ログとあまり変わりませんね。って、そりゃ当たり前か。
珍しいものは使っていません。ぶっちゃけPC本体さえあれば、他は全部タダで行けます。
エミュレータのコードはこのサイトに置いています(リンク)。マニュアルなどはないので、使い方が意味不明だと思いますし、見ても面白くないと思いますが…。
最初のコミットが6/4なので、開発期間は約2か月半です。日曜大工というか日曜プログラミングなので、割と長期間の取り組みになっています。とはいえ、フルタイムでやったとしても、実装方式などを悩む時間は変わらないので、開発期間はそんなに変わらないように思います。
前に書いたもの以外のハマりポイントをご紹介。
改良の余地はいくらでもあります。
しばらくは楽しいオモチャになりそうです。
Linux 3.12は起動するのに、Linux 3.14だとなぜか途中でハングします、なんでだろ?未だに良くわかりません。
この記事にコメントする
目次: Linux
ARMのldm命令には変わった機能が付いています。レジスタリストの後ろに付ける ^ なのですが、実は ^ には意味が2通りあります。そのためアセンブラで記述するときすこぶるわかりづらくなっています。
具体例を挙げると、下記の2つのldm命令は、同じようなレジスタリストを指定していて、同じような ^ が付いていますが、命令の意味は全く違います。
ldmdb sp, {r0, r1, r2, pc}^
ldmdb sp, {r0, r1, r2, lr}^
1つ目のldm命令は、sp - 16の指すアドレスからr0, r1, r2, pcにデータをロードして、cpsrレジスタに現在の動作モードのspsrレジスタをコピーせよ、という意味になります。
2つ目ldm命令は、sp - 16の指すアドレスから「ユーザモードの」r0, r1, r2, lrにデータをロードせよ、という意味になります。
何?意味がわからない?恐らく誰でもそうでしょう。私も最初に見たとき意味がわからなくて、目が点になりました。
なぜこんなことになるかというと、ARMのldm命令の ^ の意味が、レジスタリストに依存して変わるからです。具体的に言えば、
レジスタリストにpcレジスタが入っていたら、
「pcをロードするldm命令で、カレントモードのspsrをcpsrにコピーすることを示す」
レジスタリストにpcレジスタが入っていなかったら、
「pcをロードしないldm命令で、ユーザモードレジスタをロードすることを示す」
のようにARMの仕様で定義されているからです。
なんだその仕様は!と思われるでしょうが、この機能は、一般的なプログラムでは全く使われません。使われるのは、割り込みハンドラからの復帰、もしくは特権モードが絡む部分くらいで、いずれもOSの内部です。
そのためARMの初学者が使う可能性はほぼありません。いわゆる「わかってる」人しか使わない通の機能です。
少数のわかっている人しか使わないので、多少可読性が低くてもあまり問題が出ないのでしょう。たぶん。
と、擁護した直後に言うのは憚られますが、正直なところそこまで ^ を酷使せず、せめてどちらかを ^ じゃない別の記号にすれば良かったのにと思わんでもないです。いきなり変えたら大混乱が起きるので、今さらどうしようもありませんけど。
仕様を切るとき、特に将来も下位互換性が求められそうな仕様、オープンな仕様では、記号の一文字取っても、細心の注意が必要だよなーと、強く感じた一件でした。
この記事にコメントする
| < | 2014 | > | ||||
| << | < | 08 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| - | - | - | - | - | 1 | 2 |
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 | - | - | - | - | - | - |
25年10月6日
25年10月6日
25年9月29日
25年9月29日
20年8月24日
20年8月24日
16年2月14日
16年2月14日
25年7月20日
25年7月20日
25年7月20日
25年7月20日
25年7月20日
25年7月20日
20年8月16日
20年8月16日
20年8月16日
20年8月16日
24年6月17日
24年6月17日
wiki
Linux JM
Java API
2002年
2003年
2004年
2005年
2006年
2007年
2008年
2009年
2010年
2011年
2012年
2013年
2014年
2015年
2016年
2017年
2018年
2019年
2020年
2021年
2022年
2023年
2024年
2025年
過去日記について
アクセス統計
サーバ一覧
サイトの情報合計:
本日: