【发布时间】:2014-06-09 13:21:35
【问题描述】:
我正在尝试熟悉 Neon 说明。汇编和内在函数。我用的是 gcc V4.8.2 hardfp 我想使用带有 preload 的 NEON memcpy 来:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13544.html
我也发现了这个话题: ARM memcpy and alignment 但这与官方的 ARM 页面实现略有不同。
不幸的是,我从来没有同时使用 .s 和 .c 文件,所以我需要一些帮助。我的 .c 文件如下所示:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdint.h>
#include <arm_neon.h>
int main()
{
clock_t start, end; // timer variables
uint32_t i,X=100;
size_t size = 2048*32/* arbitrary */;
size_t offset = 1;
char* src = malloc(sizeof(char)*(size + offset));
char* dst = malloc(sizeof(char)*(size));
NEONCopyPLD( dst, src + offset, size );
memcpy( dst, src + offset, size );
return(0);
}
且 assembly.s 文件如下:
.global NEONCopyPLD
NEONCopyPLD:
PLD [r1, #0xC0]
VLDM r1!,{d0-d7}
VSTM r0!,{d0-d7}
SUBS r2,r2,#0x40
BGE NEONCopyPLD
我使用指令编译了以下程序:
arm-linux-gnueabihf-gcc -mthumb -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -Ofast -fprefetch-loop-数组 assembly.s asm_pr.c -o 输出
我收到以下错误:
potentially unexpected fatal signal 11.
CPU: 0 PID: 670 Comm: out_asm Not tainted 3.10.9-rt5+ #2
task: bf907c00 ti: bef4a000 task.ti: bef4a000
PC is at 0x4c90ce LR is at 0x852d
pc : [<004c90ce>] lr : [<0000852d>] psr: 40030030
sp : 7e958cb0 ip : 00000107 fp : 00000000
r10: 76f91000 r9 : 00000000 r8 : 00000000
r7 : 00001017 r6 : 00e85010 r5 : 00e75009 r4 : 00010001
r3 : 000f4240 r2 : 00010000 r1 : 00e75009 r0 : 00e85010
Flags: nZcv IRQs on FIQs on Mode USER_32 ISA Thumb Segment user
Control: 10c5387d Table: 4ef7404a DAC: 00000015
CPU: 0 PID: 670 Comm: out_asm Not tainted 3.10.9-rt5+ #2
Backtrace:
[<800120a4>] (dump_backtrace+0x0/0x118) from [<80012318>] (show_stack+0x20/0x24)
[<800122f8>] (show_stack+0x0/0x24) from [<804fab0c>] (dump_stack+0x24/0x28)
[<804faae8>] (dump_stack+0x0/0x28) from [<8000f560>] (show_regs+0x30/0x34)
[<8000f530>] (show_regs+0x0/0x34) from [<8003349c>](get_signal_to_deliver+0x318/0x668)
[<80033184>] (get_signal_to_deliver+0x0/0x668) from [<80011664>] (do_signal+0x11c/0x450)
[<80011548>] (do_signal+0x0/0x450) from [<80011b20>] (do_work_pending+0x74/0xac)
[<80011aac>] (do_work_pending+0x0/0xac) from [<8000e500>] (work_pending+0xc/0x20)
Segmentation fault
我的另一个问题是,我们是否可以使用 SIMD 指令(内在函数或自动向量化)来加快初始化为 0 的数组? 我注意到以下代码无法自动矢量化:
for (i=0;i<N;i++)
*(a++)=0;
但是这个代码块可以自动向量化:
for (i=0;i<N;i++)
a[i]=i;
我的最终目标是调查我是否可以拥有一个运行速度比memset() 更快的 NEON 函数。
最后我想问一些关于不可矢量化循环的问题。根据:http://gcc.gnu.org/projects/tree-ssa/vectorization.html#unvectoriz 以下代码无法自动矢量化:
while (*p != NULL) {
*q++ = *p++;
}
但是,是否可以使用内在函数或程序集来开发此循环的更快版本?如果您做过类似的事情,可以在这里发布吗?
【问题讨论】:
-
NEONCopyPLD -> "NEONCopyPLD:" 注意分号。不要在同一篇文章中提出很多(三个?)问题。关于 neon 的事情是,它是一个 SIMD 单元,它应该独立于内存速度,但是大多数实际实现都为 SIMD 提供了自己的内存端口,因此 NEON 单元可能具有更快的内存访问速度。底线是,如果您是供应商,您会知道 memset 是否应该使用 NEON,但通常它不应该比普通内核慢。
-
感谢您的评论。我改变了一些其他的东西以及插入一个半列,我能够编译。虽然我遇到了分段错误!
-
你应该一次问一件事。打扫一下,问一件事。然后,如果您还有其他问题,请发布另一个问题或等待第一个问题,看看您是否会得到您想要的。