mootoh.iphone.dev

2009-10-30

SIMD 加算

| 13:30 | はてなブックマーク - SIMD 加算 - mootoh.iphone.dev

で、さっきのコードなんだけど、ふつうに ``+'' で書くのと intrinsics 使うのとでは生成されるコードがちがう。

``+'':

   uint4 x = {0,1,2,3};
   uint4 y = {4,5,6,7};
   uint4 result = x + y;
-[neon_01AppDelegate sum]:
0000000c            b5f0        push    {r4, r5, r6, r7, lr}
0000000e            af03        add     r7, sp, #12
00000010            b085        sub     sp, #20
00000012            a30a        add     r3, pc, #40     (adr r3, 0x3c)
00000014            cb78        ldmia   r3, {r3, r4, r5, r6}
00000016            480d        ldr     r0, [pc, #52]   (0x4c)
00000018        ec443b16        vmov    d6, r3, r4
0000001c        ec465b17        vmov    d7, r5, r6
00000020        ed8d6b01        vstr    d6, [sp, #4]
00000024        ed8d7b03        vstr    d7, [sp, #12]

intrinsics

   uint4 x = {0,1,2,3};
   uint4 y = {4,5,6,7};
   uint4 result = vaddq_u32(x, y);
-[neon_01AppDelegate sum]:
0000007c            b580        push    {r7, lr}
0000007e            af00        add     r7, sp, #0
00000080            b085        sub     sp, #20
00000082        ed9f4b0c        vldr    d4, [pc, #48]   ; 0xb6
00000086        ed9f5b0d        vldr    d5, [pc, #52]   ; 0xbe
0000008a        ed9f6b0e        vldr    d6, [pc, #56]   ; 0xc6
0000008e        ed9f7b0f        vldr    d7, [pc, #60]   ; 0xce
00000092        ef266844        vadd.i32        q3, q3, q2
00000096        ed8d6b01        vstr    d6, [sp, #4]
0000009a        ed8d7b03        vstr    d7, [sp, #12]


解読中。

neon 命令を Xcode で使う

| 12:52 | はてなブックマーク - neon 命令を Xcode で使う - mootoh.iphone.dev

iPhone 3GS / touch 3G では、ARMNEON SIMD 命令が使えて胸がときめきます。ほんの少し設定すれば Xcode からもつかえる。

  1. ターゲットを ``Device'' に
  2. #include <arm_neon.h>
  3. プロジェクトの設定で、アーキテクチャを ``armv7'' に手書き、最適化を ``-O3'' に、 thumb 命令をオフに

http://gyazo.com/d12248810af88126f7d9defe20eef0be.png

"-march=armv7-a -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon" を CFLAGS につけないといけないかなーと思ってたんですが、つけたのとついてないのとで、吐かれるアセンブリが変わらないんですよね。なぞ。もっと複雑な SIMD 書くと違ってくるのかも。要追求。

iPhone 3GS か touch 3G な実機でしか動きません。

gist: 222087 - sum by ARM NEON- GitHub

- (void) sum
{
   uint4 x = {0,1,2,3};
   uint4 y = {4,5,6,7};
   //uint4 result = x + y;
   uint4 result = vaddq_u32(x, y);

   uint32_t a = *(uint32_t *)&result;
   uint32_t b = *((uint32_t *)&result +1);
   uint32_t c = *((uint32_t *)&result +2);
   uint32_t d = *((uint32_t *)&result +3);
   
   NSLog(@"result = (%u,%u,%u,%u)", a, b, c, d); // -> result = (4,6,8.10)
}

結果:

%  /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/otool -tV build/neon_01.build/Release-iphoneos/neon_01.build/Objects-normal/armv7/neon_01AppDelegate.o

....
-[neon_01AppDelegate sum]:
0000007c            b580        push    {r7, lr}
0000007e            af00        add     r7, sp, #0
00000080            b085        sub     sp, #20
00000082        ed9f4b0c        vldr    d4, [pc, #48]   ; 0xb6
00000086        ed9f5b0d        vldr    d5, [pc, #52]   ; 0xbe
0000008a        ed9f6b0e        vldr    d6, [pc, #56]   ; 0xc6
0000008e        ed9f7b0f        vldr    d7, [pc, #60]   ; 0xce
00000092        ef266844        vadd.i32        q3, q3, q2
00000096        ed8d6b01        vstr    d6, [sp, #4]
0000009a        ed8d7b03        vstr    d7, [sp, #12]
....

2009-08-11

SDK 2.2.1 用でつくってて 3.0 用にビルドしようとしてエラー

00:07 | はてなブックマーク - SDK 2.2.1 用でつくってて 3.0 用にビルドしようとしてエラー - mootoh.iphone.dev

2.2.1 時代からあるプロジェクトを、さて 3.0 用にビルドするかいな、とやってみるとコンパイルエラーになった。

http://gyazo.com/026a9a7b5861852d686f5c34cbb594b5.png

なんぞこれ、と調べてるうち、 GCC 4.0 なのがまずそうな。 プロジェクトの設定から、コンパイラのバージョンを GCC 4.2 にすると OK 。

see also: Offline - Stack Overflow

ちょっとしたはまり解決 tips でした。

2009-08-02

VFP を試す

| 23:04 | はてなブックマーク - VFP を試す - mootoh.iphone.dev

3GS が速いそうですね。うらやましくないもん! 我々には VFP があるんじゃないの!

ということで VFP (Vector Floating Point co-processor) を調べてた。

Sketchbook: iPhone VFP for n00bsチュートリアルがわかりやすい。

Xcode で新規プロジェクトをつくり、 vfp.[ch] なんてファイルを追加して

vfp.c:
void test(float * src, float * dst)
{
   
   __asm__ volatile (
                 
                 "fldmias %0!, {s8-s11} \n\t" // operations
                 "fstmias %1!, {s8-s11} \n\t"
                 : "=r" (src), "=r" (dst) // output operands
                 : "0" (src), "1" (dst) // input operands
                 : "memory" // clobbers
                 );
   
}

vfp.h:
void test(float * src, float * dst);

とか書き、ViewController とかから確認:

- (void)viewDidLoad {
    [super viewDidLoad];

   float src[4] = {0.1f, 0.2f, 0.3f, 0.4f}, dst[4] = {0.0f, 0.0f, 0.0f, 0.0f};
   test(src, dst);
   NSLog(@"%f %f %f %f", dst[0], dst[1], dst[2], dst[3]);
}

fldmias は f "LoaD" m ia s で、SIMD でロードする命令。 fstmias は f "STore" m ia s で、 SIMD でストアする命令。

ia とか s とかの詳細については ARM のリファレンスなどをみるとよいとおもいます。

そのままビルドしようとすると、

> selected processor does not support `fldmias r2!,{s8-s11}`

などとコンパイラにおこられたりするので、ターゲット → 情報を見る から、'compiled for thumb' のチェックボックスをオフにするとうまくいったりする。

これで VFP であそぶ下地ができましたね。

2009-05-29

Mac の Bonjour のサンプルを iPhone で動かす

03:12 | はてなブックマーク - Mac の Bonjour のサンプルを iPhone で動かす - mootoh.iphone.dev

mootoh’s PictureSharingIPhone at master - GitHub

MacBonjour サンプルで PictureSharing というのがあり、 iPhone でも同じように使えるように移植してみた。

ほとんどそのまま使えてすばらすい。 Cocoa すごい。

2009-02-28

Xcode での GCC オプション

21:47 | はてなブックマーク - Xcode での GCC オプション - mootoh.iphone.dev

プロジェクト内で、 .m なファイルがなくなると、プロジェクトのプロパティから GCCコンパイラオプションが消えてしまうことに気づいた。

あとからプロジェクトに .m なファイルを追加すると、コンパイラオプションが出てくることもあるし、出てこないこともある。

21:59 追記:

Xcode がとちくるってるんじゃ? と思い、 Xcode の設定ファイルを消して再チャレンジしてみた。いまのところうまくいってる。謎...

22:09 追記:

Base SDK が Device のときに、 Active SDK を Device にしたらコンパイラオプションがでてきた。 Simulator にしたら消える。逆もまたしかり。そういうものだっけ?

iPhone でもバックトレース

17:08 | はてなブックマーク - iPhone でもバックトレース - mootoh.iphone.dev

execinfo.h をつかったバックトレースは、 iPhone でもできるよという話。シミュレータ、実機のどちらでもOK。

コード: main.m

#include <execinfo.h>

void func()
{
   int j, nptrs;
#define SIZE 100
   void *buffer[SIZE];
   char **strings;
   
   nptrs = backtrace(buffer, SIZE);
   NSLog(@"backtrace() returned %d addresses\n", nptrs);
   strings = backtrace_symbols(buffer, nptrs);
   if (strings == NULL) {
      perror("backtrace_symbols");
      exit(EXIT_FAILURE);
   }
   
   for (j = 0; j < nptrs; j++)
      NSLog(@"%s\n", strings[j]);
   
   free(strings);
}

int main(int argc, char *argv[])
{    
   func();
   return 0;
}

実機で動かした結果:

2009-02-28 17:12:25.864 minimal[647:20b] backtrace() returned 3 addresses
2009-02-28 17:12:25.886 minimal[647:20b] 0   minimal                             0x00002081 start + 129
2009-02-28 17:12:25.897 minimal[647:20b] 1   minimal                             0x000020f5 start + 245
2009-02-28 17:12:25.908 minimal[647:20b] 2   minimal                             0x00002034 start + 52

なぜこれがバックトレースなのか:

% otool -tv build/Release-iphoneos/minimal.app/minimal

build/Release-iphoneos/minimal.app/minimal:
(__TEXT,__text) section
start:
00002000        e59d0000        ldr     r0, [sp]
...
_func:
0000206c            b5f0        push    {r4, r5, r6, r7, lr}
0000206e            4656        mov     r6, r10
...
_main:
000020ec            b580        push    {r7, lr}
000020ee            af00        add     r7, sp, #0
000020f0        ffbcf7ff        bl      0x206c
000020f4            2000        mov     r0, #0
000020f6            bd80        pop     {r7, pc}

0x2034 は start, 0x20f5 は _main, 0x2081 は _func の中にあることがわかりますね。

参考情報