Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何在Xcode LLVM中编写关于循环的内联汇编代码?_Iphone_C_Assembly_Arm_Inline Assembly - Fatal编程技术网

Iphone 如何在Xcode LLVM中编写关于循环的内联汇编代码?

Iphone 如何在Xcode LLVM中编写关于循环的内联汇编代码?,iphone,c,assembly,arm,inline-assembly,Iphone,C,Assembly,Arm,Inline Assembly,我在学习内联汇编。我想在iPhone中的Xcode 4 LLVM 3.0编译器下编写一个简单的例程。我成功地编写了基本的内联汇编代码 例如: int sub(int a, int b) { int c; asm ("sub %0, %1, %2" : "=r" (c) : "r" (a), "r" (b)); return c; } 我在stackoverflow.com上找到了它,它运行得非常好。但是,我不知道如何编写关于循环的代码 我需要像这样的汇编代码 void

我在学习内联汇编。我想在iPhone中的Xcode 4 LLVM 3.0编译器下编写一个简单的例程。我成功地编写了基本的内联汇编代码

例如:

int sub(int a, int b)
{
    int c;
    asm ("sub %0, %1, %2" : "=r" (c) : "r" (a), "r" (b));
    return c;
}
我在stackoverflow.com上找到了它,它运行得非常好。但是,我不知道如何编写关于循环的代码

我需要像这样的汇编代码

void brighten(unsigned char* src, unsigned char* dst, int numPixels, int intensity)
{
    for(int i=0; i<numPixels; i++)
    {
        dst[i] = src[i] + intensity;
    }
}
void变亮(无符号字符*src,无符号字符*dst,整数像素,整数强度)
{

对于(int i=0;i请看这里的循环部分-

基本上,您需要的是:

void brighten(unsigned char* src, unsigned char* dst, int numPixels, int intensity) {
    asm volatile (
                  "\t mov r3, #0\n"
                  "Lloop:\n"
                  "\t cmp r3, %2\n"
                  "\t bge Lend\n"
                  "\t ldrb r4, [%0, r3]\n"
                  "\t add r4, r4, %3\n"
                  "\t strb r4, [%1, r3]\n"
                  "\t add r3, r3, #1\n"
                  "\t b Lloop\n"
                  "Lend:\n"
                 : "=r"(src), "=r"(dst), "=r"(numPixels), "=r"(intensity)
                 : "0"(src), "1"(dst), "2"(numPixels), "3"(intensity)
                 : "cc", "r3", "r4");
}
更新:

这是霓虹灯的版本:

void brighten_neon(unsigned char* src, unsigned char* dst, int numPixels, int intensity) {
    asm volatile (
                  "\t mov r4, #0\n"
                  "\t vdup.8 d1, %3\n"
                  "Lloop2:\n"
                  "\t cmp r4, %2\n"
                  "\t bge Lend2\n"
                  "\t vld1.8 d0, [%0]!\n"
                  "\t vqadd.s8 d0, d0, d1\n"
                  "\t vst1.8 d0, [%1]!\n"
                  "\t add r4, r4, #8\n"
                  "\t b Lloop2\n"
                  "Lend2:\n"
                  : "=r"(src), "=r"(dst), "=r"(numPixels), "=r"(intensity)
                  : "0"(src), "1"(dst), "2"(numPixels), "3"(intensity)
                  : "cc", "r4", "d1", "d0");
}

所以这个NEON版本一次可以做8。但是它不会检查
numPixels
是否可以被8整除,所以你一定要这样做,否则事情会出错!无论如何,这只是向你展示可以做什么的一个开始。注意相同数量的指令,但是一次对8个像素的数据执行操作。哦,它有个s我想你也会想要在那里实现饱和。

虽然这个答案不是对你问题的直接回答,但它更像是关于汇编程序与现代编译器使用的一般性建议

在C代码的优化方面,您通常很难击败编译器。当然,通过巧妙地使用有关数据行为的特定知识,您可能只需要调整几个百分点

原因之一是现代编译器在处理您描述的代码时使用了许多技术,例如循环展开、指令重新排序以避免管道暂停和冒泡等

如果你真的想让算法尖叫,你应该考虑重新设计算法,而不是C,这样你就避免了最坏的延迟。例如,读写内存比登记访问昂贵。 实现这一点的一种方法是让代码一次加载4个字节,方法是使用

无符号long
,然后在寄存器中对此进行计算,然后将这4个字节写回一个存储操作中


总而言之,让你的算法更加智能而不是更加困难。

类似的函数也可以使用OpenGL ES和片段着色器来实现。如果这适用于你的问题。这将“免费”为你提供并行化,类似于马特建议的霓虹灯的使用。是的,你肯定可以使用OpenGL ES。这在很大程度上取决于你在做什么,以及你是否想将其作为依赖项。如果OpenGL ES需要将计算出的总和返回到CPU,则可能速度不够快。iPad GPU的制造并不能有效地执行此任务。也许他希望o作为学习练习?或者想确保NEON的矢量指令得到正确使用?看起来他想处理像素数据,这肯定会从一些矢量指令中受益。例如,如果你愿意,你可以一次添加16个像素并使其饱和。特别是在ARM上,编译器还没有达到t你想象的水平。SIMD指令和位域操作优化得很差,直接在ARM中编码可以获得很大的加速。但是请注意,AppStore只接受只使用文档化API的应用。不确定内联汇编程序如何影响AppStore资格。内联汇编决不会影响AppStore eligi可移植性。这不是使用未记录的API。内联汇编是编译器/汇编程序的功能,因此与框架的API无关。这些代码工作得非常好!这对我的理解非常有帮助。非常感谢您的建议~