- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在这里引用@auselen 的回答:Using ARM NEON intrinsics to add alpha and permute ,看起来 armcc 编译器在 NEON 优化方面比 gcc 编译器好得多。这是真的吗?我还没有真正尝试过 armcc 编译器。但是我使用带有 -O3 优化标志的 gcc 编译器得到了非常优化的代码。但现在我想知道 armcc 是否真的那么好?那么,考虑到所有因素,这两个编译器中哪个更好?
最佳答案
编译器也是软件,它们往往会随着时间的推移而改进。任何像 armcc 在 NEON 上比 GCC 更好的通用声明(或者更好的说法是矢量化)不能永远成立,因为一个开发人员团队可以通过足够的关注来缩小差距。然而,最初期望硬件公司开发的编译器更优秀是合乎逻辑的,因为他们需要展示/销售这些功能。
我最近在 Stack Overflow 上看到的一个例子是关于 answer for branch prediction .引自更新部分的最后一行“这表明即使是成熟的现代编译器在优化代码的能力方面也会有很大差异......”。
我是 GCC 的忠实粉丝,但我不会将其生成的代码质量与 Intel 或 ARM 的编译器进行比较。我希望任何主流商业编译器都能生成至少与 GCC 一样好的代码。
这个问题的一个经验答案可能是使用 hilbert-space's neon optimization example看看不同的编译器如何优化它。
void neon_convert (uint8_t * __restrict dest, uint8_t * __restrict src, int n)
{
int i;
uint8x8_t rfac = vdup_n_u8 (77);
uint8x8_t gfac = vdup_n_u8 (151);
uint8x8_t bfac = vdup_n_u8 (28);
n/=8;
for (i=0; i<n; i++)
{
uint16x8_t temp;
uint8x8x3_t rgb = vld3_u8 (src);
uint8x8_t result;
temp = vmull_u8 (rgb.val[0], rfac);
temp = vmlal_u8 (temp,rgb.val[1], gfac);
temp = vmlal_u8 (temp,rgb.val[2], bfac);
result = vshrn_n_u16 (temp, 8);
vst1_u8 (dest, result);
src += 8*3;
dest += 8;
}
}
20: f421140d vld3.8 {d1-d3}, [r1]!
24: e2822001 add r2, r2, #1
28: f3810c04 vmull.u8 q0, d1, d4
2c: f3820805 vmlal.u8 q0, d2, d5
30: f3830806 vmlal.u8 q0, d3, d6
34: f2880810 vshrn.i16 d0, q0, #8
38: f400070d vst1.8 {d0}, [r0]!
3c: e1520003 cmp r2, r3
40: bafffff6 blt 20 <neon_convert+0x20>
1e: f961 040d vld3.8 {d16-d18}, [r1]!
22: 3301 adds r3, #1
24: 4293 cmp r3, r2
26: ffc0 4ca3 vmull.u8 q10, d16, d19
2a: ffc1 48a6 vmlal.u8 q10, d17, d22
2e: ffc2 48a7 vmlal.u8 q10, d18, d23
32: efc8 4834 vshrn.i16 d20, q10, #8
36: f940 470d vst1.8 {d20}, [r0]!
3a: d1f0 bne.n 1e <neon_convert+0x1e>
void neonPermuteRGBtoBGRA(unsigned char* src, unsigned char* dst, int numPix)
{
numPix /= 8; //process 8 pixels at a time
uint8x8_t alpha = vdup_n_u8 (0xff);
for (int i=0; i<numPix; i++)
{
uint8x8x3_t rgb = vld3_u8 (src);
uint8x8x4_t bgra;
bgra.val[0] = rgb.val[2]; //these lines are slow
bgra.val[1] = rgb.val[1]; //these lines are slow
bgra.val[2] = rgb.val[0]; //these lines are slow
bgra.val[3] = alpha;
vst4_u8(dst, bgra);
src += 8*3;
dst += 8*4;
}
}
$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (crosstool-NG linaro-1.13.1-2012.05-20120523 - Linaro GCC 2012.05) 4.7.1 20120514 (prerelease)
$ arm-linux-gnueabihf-gcc -std=c99 -O3 -c ~/temp/permute.c -marm -mfpu=neon-vfpv4 -mcpu=cortex-a9 -o ~/temp/permute_gcc.o
00000000 <neonPermuteRGBtoBGRA>:
0: e3520000 cmp r2, #0
4: e2823007 add r3, r2, #7
8: b1a02003 movlt r2, r3
c: e92d01f0 push {r4, r5, r6, r7, r8}
10: e1a021c2 asr r2, r2, #3
14: e24dd01c sub sp, sp, #28
18: e3520000 cmp r2, #0
1c: da000019 ble 88 <neonPermuteRGBtoBGRA+0x88>
20: e3a03000 mov r3, #0
24: f460040d vld3.8 {d16-d18}, [r0]!
28: eccd0b06 vstmia sp, {d16-d18}
2c: e59dc014 ldr ip, [sp, #20]
30: e2833001 add r3, r3, #1
34: e59d6010 ldr r6, [sp, #16]
38: e1530002 cmp r3, r2
3c: e59d8008 ldr r8, [sp, #8]
40: e1a0500c mov r5, ip
44: e59dc00c ldr ip, [sp, #12]
48: e1a04006 mov r4, r6
4c: f3c73e1f vmov.i8 d19, #255 ; 0xff
50: e1a06008 mov r6, r8
54: e59d8000 ldr r8, [sp]
58: e1a0700c mov r7, ip
5c: e59dc004 ldr ip, [sp, #4]
60: ec454b34 vmov d20, r4, r5
64: e1a04008 mov r4, r8
68: f26401b4 vorr d16, d20, d20
6c: e1a0500c mov r5, ip
70: ec476b35 vmov d21, r6, r7
74: f26511b5 vorr d17, d21, d21
78: ec454b34 vmov d20, r4, r5
7c: f26421b4 vorr d18, d20, d20
80: f441000d vst4.8 {d16-d19}, [r1]!
84: 1affffe6 bne 24 <neonPermuteRGBtoBGRA+0x24>
88: e28dd01c add sp, sp, #28
8c: e8bd01f0 pop {r4, r5, r6, r7, r8}
90: e12fff1e bx lr
$ armcc
ARM C/C++ Compiler, 5.01 [Build 113]
$ armcc --C99 --cpu=Cortex-A9 -O3 -c permute.c -o permute_arm.o
00000000 <neonPermuteRGBtoBGRA>:
0: e1a03fc2 asr r3, r2, #31
4: f3870e1f vmov.i8 d0, #255 ; 0xff
8: e0822ea3 add r2, r2, r3, lsr #29
c: e1a031c2 asr r3, r2, #3
10: e3a02000 mov r2, #0
14: ea000006 b 34 <neonPermuteRGBtoBGRA+0x34>
18: f420440d vld3.8 {d4-d6}, [r0]!
1c: e2822001 add r2, r2, #1
20: eeb01b45 vmov.f64 d1, d5
24: eeb02b46 vmov.f64 d2, d6
28: eeb05b40 vmov.f64 d5, d0
2c: eeb03b41 vmov.f64 d3, d1
30: f401200d vst4.8 {d2-d5}, [r1]!
34: e1520003 cmp r2, r3
38: bafffff6 blt 18 <neonPermuteRGBtoBGRA+0x18>
3c: e12fff1e bx lr
关于embedded - 对于 NEON 优化,哪个更好,gcc 或 armcc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12577572/
用 ARM-NEON 编码的计算密集型算法的最佳指令吞吐量是多少? 例如,如果我有一个基于大量 8 位 -> 8 位操作的简单算法,那么可以维持的最快执行速度(以每个周期的 8 位操作衡量)是多少我们
我想为 armv6 构建我的库,如果设备支持,我会在运行时启用一些 neon 代码。 neon 代码使用 neon 内在函数,为了能够编译它,我必须启用 armeabi-v7a,但这会影响常规的 c
我正在寻找使用 NEON 内在函数测试 128 NEON 寄存器是否包含全零的最快方法。 我目前正在使用 3 个 OR 操作和 2 个 MOV: uint32x4_t vr = vorrq_u32(v
“无法加载JNI共享库“C:\ Program Files(x86)\ Java \ jre1.8.0_131 \ bin \ client \ jvm.dll” 我该如何解决此错误 最佳答案 是否根
实际上,我正在尝试找出一种比较从“unsigned short”数组加载的 NEON 寄存器值的好方法。由于我正在处理一个大型项目,因此无法解释共享整个代码部分。相反,我将分享一个类似的例子,以便每个
NEON 怎么会和 C 一样慢? 我一直在尝试构建一个快速直方图函数,通过为输入值分配一个值(这是它们最接近的范围阈值),将输入值分入范围。这是应用于图像的东西,因此它必须很快(假设图像数组为 640
我的 Zynq-7000 ARM Cortex-A9 处理器同时具有 NEON 和 VFPv3 扩展,Zynq-7000-TRM 表示处理器配置为具有“VFPv3 和高级 SIMD 指令的独立管道”。
我正在编译以下 ARM NEON 内在测试代码(在 Eclipse 和 Android NDK 中): void foo(uint64_t* Res) { uint64_t x = 0xff1
我是 NEON 内部函数(A9 处理器)的新手。 我想将 uint8x16_t 转换为 int32x4_t 值。我尝试使用 vreinterpret_s32_u8 来这样做,但没有用。 有人可以指导我
Eclipse Neon 在启动期间显示错误消息框并且不会打开。该消息提供了日志文件的文件路径。在该文件中,我看到此错误消息: !ENTRY org.eclipse.e4.ui.workbench.s
我有一个简单的单极低通滤波器(用于参数平滑),可以用以下公式解释: y[n] = (1-a) * y[n-1] + a * x[n] 如何在 ARM Neon 上有效矢量化这种情况 - 使用内在函数?
我用 polymer 构建了一个小型网络应用程序,并使用 NEON 动画。我想在特定动画(例如英雄动画和波纹动画)的自动测试中测量 fps。neon-animation中是否有animationEnd
有没有办法在保存文件时识别 Eclipse 发生了什么? 我的 Eclipse 运行速度非常慢(保存文件需要近 3 分钟)。只需在文件中添加一个空格并保存,它就会一直显示“正在更新导航器内容查看器”和
Eclipse Neon 启动后不到两分钟就不断卡住。没有显示错误消息或异常,工作台只是停止响应。 .log 文件中有无数异常,例如: !ENTRY org.eclipse.ui 4 4 2016-0
如何禁用 Eclipse Neon 中的欢迎屏幕? 虽然有 similar question for Eclipse Juno ,但建议的方法似乎在 Eclipse Neon 中不起作用。 我发现的一
我需要在 Neon 中实现以下循环。 int jump=4,c[8],i; //c[8] may be declared here int *src,sum=0; //**EDIT:** src p
这个问题在这里已经有了答案: arm neon compare operations generate negative one (2 个答案) 关闭 6 年前。 根据 Neon 文档: 如果一条车
假设我在 neon 中有一个 64 位 d 寄存器。假设它存储值 ABCDEFGH。现在我想添加 A&E、B&F、C&G、D&H 等等。这里是否有任何内在的东西可以进行这样的操作 我查看了文档,但没有
我正在努力将下面的代码翻译成 Neon Assembly。任何帮助将不胜感激。 void sum(int length, int *a, int *b, int *c, int *d, char *r
我试图改进一些代码,但我做不到,所以我在这里寻求帮助,我也尝试过使用内在函数,但是如果你想使用内在函数,你需要使用 GCC 编译器,这个编译器编译速度较慢比 LLVM,那么所有的代码都会变慢,所以最好
我是一名优秀的程序员,十分优秀!