我听说iPhone 4和iPad有一个名为VFP的fpu,它在某种程度上优化了浮点运算,甚至允许SIMD(尽管GCC是否利用了这一点是值得怀疑的).但是,我已经读到,对于某些Android设备,使用定点浮点数的加速可以导致性能提高20倍.
在这些设备中使用浮点算法实现我的代码的浮点密集部分的优点是什么.
我一直在尝试使用GCC内联汇编double将FP 加载到FPU FLD.
由于不熟悉AT&T语法并且没有在网络上找到任何内容,我非常感谢您的帮助.我的目的是要加载的地址a到EAX,然后做FLD [EAX]...
double atl(double a, int adr) {
__asm ("movl ptr %0,%%eax"::"r"(a));
__asm ("fld qword (%eax)");
//.... some other code here
__asm("movl ptr %0,%%eax"::"r"(a));
__asm("fst qword (%eax)");
return a;
}
Run Code Online (Sandbox Code Playgroud) 是否可以以查找表的形式进行浮点除法的倒数(如1/f - > 1*inv [f])?怎么做?我认为应该将一些and mask和shift应用于float以使其成为索引的一种形式?怎么会这么好?
ARM VFP指令与V和F一起开始有什么区别?
为什么ARM信息中心不再列出汇编参考中的F指令?
他们中的大多数直接映射到彼此(例如,vcvtr.s32.f32和ftosis),那么为什么它们都存在?
例如,这些函数执行相同的操作(floor float-> int conversion):
vmrs %r1, fpscr
bic %r0, %r1, #0xc00000
orr %r0, %r0, #0x800000
vmsr fpscr, %r0
vcvtr.s32.f32 %s2, %s2
vmov %r0, %s2
vmsr fpscr, %r1
mrs %r1, fpscr
bic %r0, %r1, #0xc00000
orr %r0, %r0, #0x800000
msr fpscr, %r0
ftosis %s2, %s2
fmrs %r0, %s2
msr fpscr, %r1
Run Code Online (Sandbox Code Playgroud) 我有我的数字 1.010101101,数字的类型是 REAL8,我尝试使用默认的舍入方法“四舍五入到最接近的偶数”,我看到了很多例子,它都是关于四舍五入和使用 frndint 但经过大量搜索我意识到这不是默认舍入我是对还是错?
如果是错误的,请您向我解释如何使用 MASM 程序集进行操作??
这是我的代码:
.686
.model flat,stdcall
.stack 4096
include irvine32.inc
include macros.inc
include floatio.inc
.data
R REAL8 1.010101101
.code
main proc
finit
call ShowFPUStack
fld R
call ShowFPUStack
frndint
call ShowFPUStack
exit
main endp
end main
Run Code Online (Sandbox Code Playgroud)
这是我的 FPU 堆栈
------ FPU Stack ------
------ FPU Stack ------
ST(0): +1.0101011E+000
------ FPU Stack ------
ST(0): +1.0000000E+000
Run Code Online (Sandbox Code Playgroud) 我正在学习浮点数的算法.我写了下面的代码.但是不会发生浮点异常.我的环境是Cent OS 6.4(x86_64).
请教我这个理由.
#include <stdio.h>
int
main(void)
{
double a,b,c;
unsigned short int fctr;
a=3.0;
b=0.0;
c=1.0;
asm volatile(
"fstcw %w0" // get FPU control word
:"=m"(fctr):);
printf("FPU control word= %X\n", fctr);
fctr = fctr ^ 0x4;
printf("FPU control word= %X\n", fctr);
asm volatile(
"fldcw %w0" // set operand to FPU control word
: :"m"(fctr));
asm volatile(
"fstcw %w0" // get FPU control word
:"=m"(fctr):);
printf("FPU control word= %X\n", fctr);
c = a/b;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 HPLinpack 基准测试来测量 Cortex-a57 的 GFLOPS 性能,它几乎无法达到 1 FP/周期(考虑到 2.4 GHz 时约 2.4 GFLOPS)。由于旧编译器(gcc 4.9.1)抱怨多个版本的 -mfpu= 选项,我尝试如下配置 gcc 5.0.1
../gcc/configure --with-gmp=/tmp/gcc --with-mpfr=/tmp/gcc --with-mpc=/tmp/gcc --with-libelf=/tmp/gcc --enable-语言=c,c++,fortran,go --target=aarch64-linux-gnu --prefix=/opt/another-gcc5 --with-arch=armv8-a --with-cpu=cortex-a57 --with- fpu=neon-fp-armv8
配置一切正常,但是当调用 make 时,gcc/gcc/config.gcc 中的 --with-fpu 标志崩溃了:4351
echo“该目标不支持--with-$option。” 2>&1
由于 gcc/gcc/config.gcc 3464:3467 中定义的 aarch64 架构的supported_defaults
support_defaults= aarch64 中的情况“${target}”*- - )supported_defaults =“abi cpu arch”
为什么不支持 fpu 选项?感谢任何建议,我以前从未这样做过,我有点迷失:)
我正在使用Delphi XE6执行复杂的浮点计算.我意识到浮点数的局限性,因此理解FP数中固有的不准确性.然而,在这种特殊情况下,我总是在计算结束时获得2个不同值中的1个.
第一个值和一段时间后(我还没弄清楚原因和时间),它翻转到第二个值,然后我再也无法获得第一个值,除非我重新启动我的应用程序.由于计算非常复杂,我无法更具体.我几乎可以理解这个值是否有点随机,但只有2个不同的状态有点令人困惑.这只发生在32位编译器中,无论我尝试多少次,64位编译器都会给出一个答案.这个数字与32位计算中的2不同,但我理解为什么会发生这种情况,我很好.我需要一致性,而不是完全准确性.
我唯一怀疑的是,在一些影响后续计算的计算之后,FPU可能会处于某种状态,因此我的问题是清除所有寄存器和FPU堆栈以平衡竞争场.在开始计算之前,我打电话给这个CLEARFPU.
经过一番调查,我意识到我在找错了地方.你看到的不是浮点数所得到的.我正在查看数字的字符串表示,并认为这里有4个数字进入计算ALL EQUAL,结果是不同的.事实证明这些数字似乎只是相同.我开始记录数字的十六进制等效值,回过头来找到一个外部dll,用于矩阵乘法导致错误.我用Delphi编写的例程替换了矩阵乘法,一切都很好.
由于我的主要操作系统是linux并且在visual studio上有项目,所以我决定使用在线编译器来实现它.我发现这是很多人提出的.所以这是我的代码:
#include <iostream>
using namespace std;
int main(void) {
float a = 1;
float b = 20.2;
float res = 0;
float res1 = 0;
_asm {
FLD a
FCOM b
JA midi
JMP modi
midi:
FST res
JMP OUT
modi:
FST res1
JMP OUT
}
OUT:
cout << "res = " << res << endl;
cout << "res1 = " << res1 << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的目标很简单,如果a是大于b不是把a在res,否则 …
英特尔®64和IA-32体系结构软件开发人员手册(第2卷)表示,对于FST / FSTP FPU指令F 受影响的标志:
简单的测试(几乎没有任何价值)告诉我,C0,C2,C3不会受到影响:
#include <iostream>
#include <bitset>
#include <cstdlib>
#include <cstdint>
int main()
{
double x = -1.0;
std::uint16_t a = 0, b = 0;
asm volatile ("fld %[x] ; ftst ; fnstsw %%ax ; mov %%ax, %[a] ; fstp %%st ; fnstsw %%ax ; mov %%ax, %[b] ;"
: [a]"=m"(a), [b]"=m"(b)
: [x]"t"(x)
: "cc", "memory");
std::cout << std::bitset< 16 >(a) << std::endl;
std::cout << std::bitset< 16 …Run Code Online (Sandbox Code Playgroud)