在ARM Cortex-A8处理器中,我了解NEON是什么,它是一个SIMD协处理器.
但VFP(矢量浮点)单元也是一个协处理器,可以作为SIMD处理器使用吗?如果是这样哪个更好用?
我读了几个链接,如 -
但不是很清楚他们的意思.他们说VFP从未打算用于SIMD,但在Wiki上我读了以下内容 - " VFP架构还支持短向量指令的执行,但这些指令依次对每个向量元素进行操作,因此不提供真正的SIMD性能(单指令多数据并行. "
它不是很清楚要相信什么,任何人都可以详细说明这个话题吗?
这是一个C++代码:
#define ARR_SIZE_TEST ( 8 * 1024 * 1024 )
void cpp_tst_add( unsigned* x, unsigned* y )
{
for ( register int i = 0; i < ARR_SIZE_TEST; ++i )
{
x[ i ] = x[ i ] + y[ i ];
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个霓虹灯版本:
void neon_assm_tst_add( unsigned* x, unsigned* y )
{
register unsigned i = ARR_SIZE_TEST >> 2;
__asm__ __volatile__
(
".loop1: \n\t"
"vld1.32 {q0}, [%[x]] \n\t"
"vld1.32 {q1}, [%[y]]! \n\t"
"vadd.i32 q0 ,q0, q1 \n\t"
"vst1.32 {q0}, …Run Code Online (Sandbox Code Playgroud) ARM参考手册没有详细介绍各个指令(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348b/BABIIBBG.html).有没有更详细的东西?
我正在尝试为Cortex A9 ARM处理器(更具体的OMAP4)构建一个库,我对于哪些\何时在浮点运算和SIMD中使用NEON vs VFP有点困惑.需要注意的是,我知道2个硬件协处理器单元之间的区别(这也在SO上有所描述),我对它们的正确使用有一些误解.
与此相关我使用以下编译标志:
GCC
-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
ARMCC
--cpu=Cortex-A9 --apcs=/softfp
--cpu=Cortex-A9 --fpu=VFPv3 --apcs=/softfp
Run Code Online (Sandbox Code Playgroud)
我已经阅读了ARM文档,很多wiki(比如这个),论坛和博客文章,每个人似乎都同意使用NEON比使用VFP或至少混合NEON更好(例如使用instrinsics来实现一些算法在SIMD中)和VFP并不是一个好主意; 如果这适用于整个application\library的上下文或仅适用于代码中的特定位置(函数),我还不是100%确定.
所以我在我的应用程序中使用neon作为FPU,因为我也想使用内在函数.结果我遇到了一些麻烦,我对如何在Cortex A9上最好地使用这些功能(NEON vs VFP)的困惑只是进一步深化而不是清理.我有一些代码为我的应用程序进行基准测试,并使用一些自定义的计时器类,其中计算基于双精度浮点.使用NEON作为FPU会产生完全不合适的结果(尝试打印这些值会导致打印主要是inf和NaN;相同的代码在为x86构建时没有任何障碍).所以我改变了我的计算以使用单精度浮点,据记载,NEON不处理双精度浮点.我的基准测试仍然没有给出正确的结果(最糟糕的是现在它在x86上不再起作用了;我认为这是因为精度的损失,但我不确定).所以我几乎完全迷失了:一方面我想使用NEON用于SIMD功能并使用它,因为FPU没有提供正确的结果,另一方面将它与VFP混合似乎不是一个好主意.在这方面的任何建议将不胜感激!!
我在上面提到的wiki的文章中找到了在NEON上下文中浮点优化应该做些什么的总结:
"
对于softfp:
"
我不能用于浮动ABI,因为我无法链接到我可用的库.大多数的推荐对我来说都是有意义的(除了"快速模式",我不明白应该做什么以及此时我能做得比编译器更好的事实)但我不断得到不一致的结果和我现在不确定.
任何人都可以了解如何正确使用浮点和NEON用于Cortex A9/A8以及我应该使用哪些编译标志?
我想了解更多Android手机上使用的CPU.原因是我们正在构建C库,它具有我们可以设置的某些CPU /数学处理器架构标志.
到目前为止,我们发现所有Android设备的CPU都是ARM设计,并且是ARMv6(旧设备,低端,华为,中兴,小型SE)或ARMv7(Honeycomb平板电脑和所有更昂贵的设备,几乎都具有WVGA和更高的分辨率)我检查了~20台设备,并且都有这种类型的处理器.那是对的吗?还有其他人吗?
现在谈到多媒体和数学运算时,我认为两个单元很重要 - 用于浮点运算的VFP和SIMD- NEON.在测试了上面提到的一组设备后,我发现几乎所有设备都支持VFP,而NEON则不支持.对此有何评论?
我不知道ARMv6和ARMv7的区别究竟是什么(除了一般的速度).现在我们正在构建一个多媒体C库,它有几个用于构建的标志.我的问题是如何在一侧定位最大数量的设备以及如何允许更好设备的用户使用他们的硬件.我的建议是准备3个不同的版本:ARMv6/VFP,ARMv7/VFP和ARMv7/VFP/NEON.其他提案?
在ARMv6的/ VFP我认为应该对所有配置下运行,除了设备,其缺少VFP(如旧的HTC野火) -但这些仍然不支持的.
这是一个好方法吗?欢迎任何评论.
此致,STeN
我正在开发一个可以进行实时图像处理的iPhone应用程序.其管道中最早的步骤之一是将BGRA图像转换为灰度图像.我尝试了几种不同的方法,时间结果的差异远大于我想象的可能.首先我尝试使用C.我通过添加B + 2*G + R/4来近似转换为光度
void BGRA_To_Byte(Image<BGRA> &imBGRA, Image<byte> &imByte)
{
uchar *pIn = (uchar*) imBGRA.data;
uchar *pLimit = pIn + imBGRA.MemSize();
uchar *pOut = imByte.data;
for(; pIn < pLimit; pIn+=16) // Does four pixels at a time
{
unsigned int sumA = pIn[0] + 2 * pIn[1] + pIn[2];
pOut[0] = sumA / 4;
unsigned int sumB = pIn[4] + 2 * pIn[5] + pIn[6];
pOut[1] = sumB / 4;
unsigned int sumC = pIn[8] + 2 * pIn[9] …Run Code Online (Sandbox Code Playgroud) 我在哪里可以找到有关常见SIMD技巧的信息?我有一个指令集,知道如何编写非棘手的SIMD代码,但我知道,SIMD现在功能更强大.它可以保存复杂的条件无分支代码.
例如(ARMv6),以下指令序列将Rd的每个字节设置为等于Ra和Rb的相应字节的无符号最小值:
USUB8 Rd, Ra, Rb
SEL Rd, Rb, Ra
Run Code Online (Sandbox Code Playgroud)
教程/非常见SIMD技术的链接也很好:) ARMv6对我来说是最有趣的,但x86(SSE,...)/ Neon(在ARMv7中)/其他也很好.
我试图找到一个函数的优化C或汇编程序实现,它将两个4x4矩阵相互相乘.该平台是基于ARM6或ARM7的iPhone或iPod.
目前,我正在使用一种相当标准的方法 - 只需一点循环展开.
#define O(y,x) (y + (x<<2))
static inline void Matrix4x4MultiplyBy4x4 (float *src1, float *src2, float *dest)
{
*(dest+O(0,0)) = (*(src1+O(0,0)) * *(src2+O(0,0))) + (*(src1+O(0,1)) * *(src2+O(1,0))) + (*(src1+O(0,2)) * *(src2+O(2,0))) + (*(src1+O(0,3)) * *(src2+O(3,0)));
*(dest+O(0,1)) = (*(src1+O(0,0)) * *(src2+O(0,1))) + (*(src1+O(0,1)) * *(src2+O(1,1))) + (*(src1+O(0,2)) * *(src2+O(2,1))) + (*(src1+O(0,3)) * *(src2+O(3,1)));
*(dest+O(0,2)) = (*(src1+O(0,0)) * *(src2+O(0,2))) + (*(src1+O(0,1)) * *(src2+O(1,2))) + (*(src1+O(0,2)) * *(src2+O(2,2))) + (*(src1+O(0,3)) * *(src2+O(3,2)));
*(dest+O(0,3)) = (*(src1+O(0,0)) * *(src2+O(0,3))) + (*(src1+O(0,1)) * *(src2+O(1,3))) … 什么是iOS/Android ARM设备最快的FFT库?人们通常在iOS/Android平台上使用什么库?我猜vDSP是iOS上最常用的库.
编辑:我的代码是http://anthonix.com/ffts并使用BSD许可证.它在Android和iOS上运行,比libav,FFTW和vDSP更快.
EDIT2:如果有人可以访问POWER7机器(或其他机器),请给我发电子邮件.非常感谢.
干杯,
我当时正在处理四个像素的图像,这armv7适用于Android应用程序.
我想float32x4_t用另一个向量来划分一个向量,但是它中的数字从大约0.7到有不同,在3.85我看来,除法的唯一方法是使用右移,但这是一个数字2^n.
此外,我是新手,所以欢迎任何建设性的帮助或评论.
例:
如何使用NEON内在函数执行这些操作?
float32x4_t a = {25.3,34.1,11.0,25.1};
float32x4_t b = {1.2,3.5,2.5,2.0};
// somthing like this
float32x4 resultado = a/b; // {21.08,9.74,4.4,12.55}
Run Code Online (Sandbox Code Playgroud)