目次: Linux
自作ARMエミュレータ上でLinux 3.14.16も起動しました。
実行速度が遅いのは相変わらずですが、ちょっとしたキャッシュを入れたおかげで、従来比2倍くらいになりました。下記はCore2 Quad Q9550での実行結果です。
Connected to the target VM, address: '127.0.0.1:59905', transport: 'socket' Exception: Reset by 'Init.'. loadFile: Z:\arm_cross\linux-3.14.16\arch\arm\boot\Image loadFile: 'Z:\arm_cross\linux-3.14.16\arch\arm\boot\Image' done, 3912512bytes. loadFile: Z:\arm_cross\work\initramfs.gz loadFile: 'Z:\arm_cross\work\initramfs.gz' done, 1113122bytes. UARTFBRD: 0x00000004 UARTIBRD: 0x00000027 UARTLCR_H: 0x00000070 [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 3.14.16+ (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) ) #7 Tue Sep 2 00:29:04 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: Data cache writeback [ 0.000000] On node 0 totalpages: 16384 [ 0.000000] free_area_init_node: node 0, pgdat c03c2c18, node_mem_map c3f7a000 [ 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.001122] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns [ 0.007939] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [ 0.009354] pcpu-alloc: [0] 0 [ 0.016694] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 [ 0.017822] Kernel command line: console=ttyAMA0 mem=64M lpj=0 root=/dev/ram init=/bin/sh debug printk.time=1 [ 0.034226] PID hash table entries: 256 (order: -2, 1024 bytes) [ 0.037649] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) [ 0.051346] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.171196] Memory: 59872K/65536K available (2809K kernel code, 156K rwdata, 732K rodata, 115K init, 116K bss, 5664K reserved) [ 0.176299] Virtual kernel memory layout: [ 0.176299] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.176299] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) [ 0.176299] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB) [ 0.176299] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB) [ 0.176299] modules : 0xbf000000 - 0xc0000000 ( 16 MB) [ 0.176299] .text : 0xc0008000 - 0xc037d840 (3543 kB) [ 0.176299] .init : 0xc037e000 - 0xc039ac8c ( 116 kB) [ 0.176299] .data : 0xc039c000 - 0xc03c3340 ( 157 kB) [ 0.176299] .bss : 0xc03c3340 - 0xc03e0694 ( 117 kB) [ 0.194996] NR_IRQS:224 [ 0.311103] VIC @f1140000: id 0x00041190, vendor 0x41 [ 0.334340] FPGA IRQ chip 0 "SIC" @ f1003000, 13 irqs, parent IRQ: 63 [ 0.421699] Console: colour dummy device 80x30 [ 0.426511] Calibrating delay loop... 15.18 BogoMIPS (lpj=75904) [ 1.453855] pid_max: default: 32768 minimum: 301 [ 1.470559] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 1.471997] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 1.549273] CPU: Testing write buffer coherency: ok [ 1.567848] Setting up static identity map for 0x802ac900 - 0x802ac958 [ 1.792641] VFP support v0.3: no double precision support [ 1.826380] NET: Registered protocol family 16 [ 1.913054] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 2.222332] Serial: AMBA PL011 UART driver [ 2.232115] dev:f1: ttyAMA0 at MMIO 0x101f1000 (irq = 44, base_baud = 0) is a PL011 rev1 [ 2.471302] console [ttyAMA0] enabled [ 2.506242] dev:f2: ttyAMA1 at MMIO 0x101f2000 (irq = 45, base_baud = 0) is a PL011 rev1 [ 2.542220] dev:f3: ttyAMA2 at MMIO 0x101f3000 (irq = 46, base_baud = 0) is a PL011 rev1 [ 2.580195] fpga:09: ttyAMA3 at MMIO 0x10009000 (irq = 70, base_baud = 0) is a PL011 rev1 [ 3.207538] bio: create slab <bio-0> at 0 [ 3.444611] Switched to clocksource timer3 [ 4.365563] NET: Registered protocol family 2 [ 4.453045] TCP established hash table entries: 1024 (order: 0, 4096 bytes) [ 4.465491] TCP bind hash table entries: 1024 (order: 0, 4096 bytes) [ 4.474190] TCP: Hash tables configured (established 1024 bind 1024) [ 4.482792] TCP: reno registered [ 4.485464] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 4.493590] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 4.522323] NET: Registered protocol family 1 [ 4.552290] RPC: Registered named UNIX socket transport module. [ 4.555861] RPC: Registered udp transport module. [ 4.559377] RPC: Registered tcp transport module. [ 4.562420] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 4.599499] Trying to unpack rootfs image as initramfs... [ 41.046708] Freeing initrd memory: 1084K (c0800000 - c090f000) [ 41.069328] NetWinder Floating Point Emulator V0.97 (double precision) [ 41.141637] futex hash table entries: 256 (order: -1, 3072 bytes) [ 41.206487] Installing knfsd (copyright (C) 1996 okir@monad.swb.de). [ 41.221841] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc. [ 41.248434] ROMFS MTD (C) 2007 Red Hat, Inc. [ 41.252843] msgmni has been set to 119 [ 41.288910] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) [ 41.292702] io scheduler noop registered [ 41.294993] io scheduler deadline registered [ 41.299488] io scheduler cfq registered (default) [ 42.651584] brd: module loaded [ 42.698604] physmap platform flash device: 04000000 at 34000000 [ 42.799677] physmap-flash physmap-flash.0: map_probe failed [ 42.938847] smc91x: not found (-19). [ 42.980983] mousedev: PS/2 mouse device common for all mice [ 43.023922] ledtrig-cpu: registered to indicate activity on CPUs [ 43.175215] TCP: cubic registered [ 43.177334] NET: Registered protocol family 17 UARTIFLS: 0x00000012 UARTFBRD: 0x00000000 UARTIBRD: 0x00000001 UARTLCR_H: 0x00000000 UARTFBRD: 0x00000000 UARTIBRD: 0x00000000 UARTLCR_H: 0x00000070 UARTFBRD: 0x00000004 UARTIBRD: 0x00000027 UARTLCR_H: 0x00000070 [ 43.361101] Freeing unused kernel memory: 112K (c037e000 - c039a000) hello, world!! /bin/sh: can't access tty; job control turned off UARTFBRD: 0x00000004 UARTIBRD: 0x00000027 UARTLCR_H: 0x00000070 / #
実行速度が速いと時間当たりの試行回数を増やせて、デバッグ効率が良くなるので、実行速度って結構、大事だったりします。
以前、ハングしていた箇所はPL110 Color LCDドライバでした。今のところカーネルコンフィグを変え、PL110ドライバをコンパイル対象から外すことで、ハングを回避しています。
それだけで1週間掛かっちゃう?って思った方はスルドイです…。本当のところを言うと「ハングはイケてないぜ、直すぜー!」と思ってPL110のLinuxドライバのコードを見ていましたが、どう直したもんかわからず、諦めたのです…。
なぜかPL110のドライバはPL110とPL111(次世代コア)のレジスタアドレスが両方書いてあって、どちらのコア用の制御なのかがわかりませんでした。一応、どちらの仕様書も持っていますから、最悪、両方作って試せば良いのですけど、さすがに面倒すぎる…。
おそらく私が何か勘違いしているだけの可能性大なのと、LCDのエミュレーションはまだやるつもりがないので、この件は頭の隅で細々と考えることにします。
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に加筆。
< | 2014 | > | ||||
<< | < | 09 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | 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 | - | - | - | - |
合計:
本日: