iOS-使用Accelerate.framework对矢量进行逐位异或



我正在尝试在预定值和数组的每个元素之间执行bitwise XOR

这显然可以在这样的循环中完成(在伪代码中):

int scalar = 123;
for(int i = 0; i < VECTOR_LENGTH; i++) {
int x_or = scalar ^ a[i];
}

但我开始通过使用Accelerate.framework了解性能增强。

我正在查看Accelerate.framework的文档,但我还没有看到基于元素的bitwise XOR有人知道这是否可能吗

Accelerate没有实现有问题的操作。然而,您可以很容易地编写自己的矢量代码来实现这一点。曾经很好的方法是使用clang向量扩展:

#include <stddef.h>
typedef int vint8 __attribute__((ext_vector_type(8),aligned(4)));
typedef int vint4 __attribute__((ext_vector_type(4),aligned(4)));
typedef int vint2 __attribute__((ext_vector_type(2),aligned(4)));
int vector_xor(int *x, size_t n) {
vint8 xor8 = 0;
while (n >= 8) {
xor8 ^= *(vint8 *)x;
x += 8;
n -= 8;
}
vint4 xor4 = xor8.lo ^ xor8.hi;
vint2 xor2 = xor4.lo ^ xor4.hi;
int xor = xor2.lo ^ xor2.hi;
while (n > 0) {
xor ^= *x++;
n -= 1;
}
return xor ^ 123;
}

这非常好,因为(a)它不需要使用内部函数,(b)它不将您与任何特定的体系结构联系在一起。它为您编译的任何体系结构生成了相当不错的代码。另一方面,它将您与clang联系在一起,而如果您使用内部函数,您的代码也可以与其他编译器一起使用。

Stephen的答案很有用,但当您查看Accelerate时,请记住它不是一个神奇的"快速"库。除非VECTOR_LENGTH非常大(比如10000——编辑:Stephen不同意这个规模,并且倾向于比我更了解这个主题;见评论),否则函数调用的成本通常会超过你所获得的任何好处。记住,归根结底,Accelerate只是代码。通常情况下,像您这样的简单手工编写的循环(尤其是使用良好的编译器优化)在像xor这样的简单操作上会同样好或更好。

但在许多情况下,您需要让编译器来帮助您。Clang知道如何自动进行各种有用的向量优化(就像Stephen的回答一样)。但在大多数情况下,默认的优化设置是-Os(最快,最小)。这意味着"clang,你可以做任何你想做的优化,但如果它使生成的二进制文件变得更大,就不行了。"你可能会注意到Stephen的例子比你的例子大一点。这意味着编译器经常被禁止应用它知道如何进行的自动矢量优化

但是,如果你切换到-Oast,那么你就允许clang提高性能,即使它增加了二进制大小(在现代硬件上,甚至是移动硬件上,这通常是一个很好的折衷方案)。在"构建设置"面板中,这被称为"优化级别:最快、最激进的优化"。几乎在所有情况下,这都是iOS和OS X应用程序的正确设置。(由于历史原因,它目前不是默认的;我预计苹果公司将来会将其作为默认。)

关于Accelerate的局限性的更多讨论(它是一个很棒的库),你可能会对"Fast Bézier简介(和尝试Accelerate.framework)"感兴趣。我还强烈推荐"LLVM编译器的新增功能"(WWDCS 2013的第402期),我发现它比Accelerate简介更有用。Clang可以做一些非常惊人的优化,如果你避开它的方式。

最新更新