Consistent FPS or ms/frame in Mac OS X.

Oh for Swift. Afaik Swift doesn't support simd/neon intrinsic stuff. It needs to be in compiler/language. Currently it isn't. Not sure if Apple will have it. I think Swift can interoperate with C trivially. So you could create small C function (DrawRectangleQuickly) that performs performance related function using simd or neon and call that for Swift

Can I just cast it instead of converting it? Or is that semantically different?
What exactly do you want to get in result?
Same bitwise representation 10100101 stays the same 10100101 in memory? Or do you need to cast values 123 == 123.0f. In first case you cast as pointer (reinterpret_cast in C++), in second case you do "regular" cast (static_cast in C++).
Thank you for your clear answer about casts! :)

Regarding simd in Swift: this week Apple started supporting simd in Swift, but for some weird reason __m128i is not defined, and neither are functions with __m128i as return value or argument. (Unless I did something wrong)

According to Microsoft __m128i is not supported on ARM (which is interesting in various ways to me, for one, why wouldn't _one_ be supported and not the other? Two, it implies __m128 is supported for ARM which isn't NEON.)
Microsoft MSDN __m128i

My only explanation is that since Apple mostly cares about iOS, they don't support __m128i yet.

Edited by elle on
__m128 is 100% NOT supported in ARM. No SSE or AVX type is supported (__m128d, __m256, etc...)
If you want proof in MSDN docs: https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx
The __m128 data type is not supported on ARM processors.

For ARM you have NEON types from arm_neon.h header (no idea how it will work from Swift): http://www.opensource.apple.com/s...cc-5664/gcc/config/arm/arm_neon.h
 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
typedef __builtin_neon_qi int8x8_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_hi int16x4_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_si int32x2_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_di int64x1_t;
typedef __builtin_neon_sf float32x2_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_poly8 poly8x8_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_poly16 poly16x4_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_uqi uint8x8_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_uhi uint16x4_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_usi uint32x2_t	__attribute__ ((__vector_size__ (8)));
typedef __builtin_neon_udi uint64x1_t;
typedef __builtin_neon_qi int8x16_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_hi int16x8_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_si int32x4_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_di int64x2_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_sf float32x4_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_poly8 poly8x16_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_poly16 poly16x8_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_uqi uint8x16_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_uhi uint16x8_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_usi uint32x4_t	__attribute__ ((__vector_size__ (16)));
typedef __builtin_neon_udi uint64x2_t	__attribute__ ((__vector_size__ (16)));

typedef __builtin_neon_sf float32_t;
typedef __builtin_neon_poly8 poly8_t;
typedef __builtin_neon_poly16 poly16_t;

...etc


Same for MSVC: https://msdn.microsoft.com/en-us/library/hh875058.aspx
NEON intrinsics are supported, as provided in the header file arm_neon.h. The Visual C++ compiler support for NEON intrinsics resembles that of the ARM compiler, which is documented in Appendix G of the ARM Compiler toolchain, Version 4.1 Compiler Reference on the ARM Infocenter website.

Edited by Mārtiņš Možeiko on
Oh, ok. Thanks. I should be doing something wrong then. I should've read the MSDN docs more carefully. :blush:

Question for owensd: Is __m128i defined in Swift for you if you import <x86intrin.h> via an Objective-C Bridging Header?

Edited by elle on
So the timing issues were due to running the game update and render loop on a separate thread. I figured out how to dispatch events, and now, when I do exactly the same on the main thread I hit 20 fps consistently.

My question with SIMD in Swift remains. If there's anyone who could check if for them __m128i is also undefined, while __m128 is not, I'd appreciate it.

Edited by elle on
Does Swift have includes/imports? How can you use __m128? Can you open and see source where it or _mm_* functions are defined?

Edited by Mārtiņš Možeiko on
I thought of viewing the header files, too, and it's very weird! So, Swift cannot include header files directly, only "modules". But it can import header files by adding an Objective-C file that includes the header file to the project.

I can use the __m128i types without problem in c/objective-c but not in swift, and I can see their definitions in the header files. Anyway, it might be a bug, but I would think I'd heard from it already somewhere...
Dpn't know how it is in Swift, but in ObjC importing and including header is almost same thing. Import simply makes sure header is included once (so you kind of don't need #ifdef/#pragma once header guard). That's the only difference.

And on ObjC SSE types come from regular C headers: __m128 comes from xmmintrin.h and __m128i comes from emmintrin.h. You include them in ObjC source and can use all the _mm_* functions you want. No idea about Swift :)
This is how you do SIMD in Swift: http://www.russbishop.net/swift-2-simd
You include simd.h header and operate with abstract intX or floatX types. Swift+LLVM compiler will lower them automatically to SSE or NEON instructions depending on what target you are compiling for (x86 vs ARM).