iPhone检测处理器型号/支持NEON

10

我正在寻找一种在运行时区分配备有新ARM处理器的设备(例如iPhone 3GS和部分iPods 3G)与装备旧ARM处理器的设备的方法。

我知道可以使用uname()函数确定设备型号,但由于只有部分iPod Touch 3G获得了ARM处理器的提升,这不足够。

因此,我正在寻找以下其中之一:

  1. 检测处理器型号的方法-我认为没有这种方法。
  2. 确定是否支持ARM NEON指令的方法-从中我可以推导出答案。
  3. 确定设备总存储大小的方法-将其与已知的设备型号结合起来,可能会hackishly地得出答案。
  4. <输入随机想法>

提前感谢:)


好问题!我刚刚查了Omap3参考手册,发现协处理器寄存器中的指令集支持位无法从用户模式访问... - Nils Pipenbrinck
到底是为了什么?似乎无论你在应用程序中试图做出什么决定,都可能有一种能力可以进行测试,而不是通过处理器型号来侧面解决问题。 - Sixten Otto
1
我正在进行密集计算。我不确定可以测试什么能力。我可以测量性能并根据其进行调整,这听起来像是一个好方法,但我担心在我的情况下这相当困难。我很难相信没有办法知道是否可用NEON指令。 - yonilevy
4个回答

12

虽然不是你所问的内容,但一个简单的解决方案是将应用程序构建成fat二进制文件,这样它就包含了ARMv6和ARMv7的可执行代码。如果你这么做了,适当的代码将自动在处理器上运行,你不需要进行任何运行时检查。实际上,你让加载器为你做了运行时检测。

要做到这一点,请将XCode项目中的架构设置从“标准(armv6)”更改为“优化(armv6 armv7)”

然后,在你的实现中,你可以这样做:

#if defined __ARM_NEON__
    // Code that uses NEON goes here
#else  // defined __ARM_NEON__
    // Fallback code without NEON goes here
#endif // defined __ARM_NEON__

有一个类似的宏可以用来检测(非 NEON)ARMv7 特性,但我暂时想不起来了。

如果您真的想进行运行时分派,请查看 libc 中的 sysctlbyname 函数。 具体来说,我认为查找 HW_MACHINE_ARCH 参数可能对您有用。


我需要检查sysctlbyname是否能够提供我所需的信息。不幸的是,我手头没有新处理器的iPod,所以我无法测试。有人尝试过吗?这可能是最终的方法,但它确实取决于那里定义了什么。 - yonilevy
2
当编译面向具有NEON的ARMv7处理器(包括3GS和第三代iPod Touch)时,编译器将定义__ARM_NEON__宏。 - Stephen Canon
1
除非在非常特殊的情况下,否则没有理由在运行时进行检查。话虽如此,是的,该API在两个平台上都可用,并且可以使用。 - Stephen Canon
我不太同意 - 如果你只需要检查一小段代码,制作一个fat二进制文件将会使你的Mach-o可执行文件大小翻倍,而运行时检查则不会。不幸的是,sysctl(byname)不起作用:由于未知原因,hw.machine / HW_MACHINE实际上返回模型(例如“iPod2,1”),而hw.machinearch / HW_MACHINE_ARCH则返回错误。幸运的是,我已经找到了一种方法。 - Pierre Lebeaupin
1
@Pierre:一般来说,可执行文件的大小只占应用程序总大小的一小部分。磁盘上的大部分空间都被图形、声音、文本、nib文件和其他在多个架构之间共享的资源所占用。虽然构建fat可能会使您的mach-o二进制文件的大小增加一倍,但通常只会导致应用程序整体大小的微小增加,并且通常值得为其带来的性能优势付出代价。 - Stephen Canon
显示剩余2条评论

5

我能想到的一个解决方法是检测OpenGL ES 2.0是否可用,因为新的处理器支持它。

mobileorchard上有一篇关于如何做到这一点的文章。


谢谢,这实际上是一种相当不错的实现这个hack的方式。然而唯一的缺点是,判断OpenGL ES 2.0是否可用的唯一方法是通过调用EAGLContext :: initWithAPI并检查返回值,这意味着将OpenGL引入我的项目中。无论如何,除非我找到更好的方法,否则我可能会这样做。 - yonilevy
是的,我同意这很遗憾,而且可能是一项繁重的操作,只是为了确定设备的能力。 - pgb

1

编辑:我已经撤回了这个答案,因为后来我发现一个明显的漏洞:当我们在一些未来硬件上得到一个未知的子类型时该怎么办?这不是面向未来的。此外,由于苹果对使用未记录的API零容忍的态度,并且该API文档状态的不确定性也没有帮助。

您应该使用Stephen Canon的答案并构建您的应用程序。可靠的、面向未来的运行时检测目前是不可行的(我向您保证,这让我非常失望)。


0

我知道这很糟糕,但我能想到的最好的方法就是检测设备是否支持视频录制。目前只有基于ARM7的iPhone和iPod设备支持它,因此我认为这是一种合法的方式。

要做到这一点,可以使用UIImagePickerController的availableMediaTypesForSourceType与kUTTypeMovie的isSourceTypeAvailable结合使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接