我知道x87具有更高的内部精度,这可能是人们在它与SSE操作之间看到的最大差异.但我不得不怀疑,使用x87还有其他好处吗?我有-mfpmath=sse在任何项目中自动输入的习惯,我想知道我是否遗漏了x87 FPU提供的任何其他内容.
你能帮我理解在Win32平台上我的Delphi应用程序中FPU Control Word的运行情况.
当我们创建一个新的VCL应用程序时,控制字设置为1372h.这是我不明白的第一件事,为什么它是1372h而不是1332h,这是Default8087CW在System单位中定义的.
这两者之间的区别:
1001101110010 //1372h
1001100110010 //1332h
Run Code Online (Sandbox Code Playgroud)
是根据文档保留或不使用的第6位.
第二个问题是CreateOleObject.
function CreateOleObject(const ClassName: string): IDispatch;
var
ClassID: TCLSID;
begin
try
ClassID := ProgIDToClassID(ClassName);
{$IFDEF CPUX86}
try
Set8087CW( Default8087CW or $08);
{$ENDIF CPUX86}
OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IDispatch, Result));
{$IFDEF CPUX86}
finally
Reset8087CW;
end;
{$ENDIF CPUX86}
except
on E: EOleSysError do
raise EOleSysError.Create(Format('%s, ProgID: "%s"',[E.Message, ClassName]),E.ErrorCode,0) { Do not localize }
end;
end;
Run Code Online (Sandbox Code Playgroud)
上面的功能是将控制字改为137Ah,所以它打开第3位(溢出掩码).我不明白为什么要调用它Reset8087CW,而不是恢复进入函数之前的单词状态?
(问题在最后)
我正在对第三方COM组件产生严重的头痛,这些组件不断更改FPU控制字.
我的开发环境是Windows和Visual C++ 2008.普通的FPU控制字指定在各种条件下不应抛出任何异常.我已经通过查看中_CW_DEFAULT找到的宏float.h以及在启动时查看调试器中的控制字来验证这一点.
每次我调用COM对象时,控制字在返回时被修改.这很容易防御.我只是重置控制字,一切都很好.问题是当COM组件开始调用我的事件接收器时.我可以在收到事件调用后立即通过重置控制字来保护我的代码,但是一旦从事件调用返回,我就无法做任何事情.
我没有此COM组件的源代码,但我与作者联系.我从他那里得到的回答是"嗯?".我不认为他对我正在谈论的内容有任何线索,所以我担心自己必须对此做些什么.我相信他的运行时(我认为它是Delphi或Borland C++,因为DLL中充满了符号名称,都以大写字母T开头),或者他正在使用的其他一些第三方代码,这导致了问题.我不认为他的代码明确地修改了FPU控制字.
那么,我该怎么办?从业务角度来看,必须使用此第三方组件.从技术角度来看,我可以抛弃它,并自己实现通信协议.然而,这将是非常昂贵的,因为该协议涉及处理信用卡交易.我们不想承担责任.
我迫切需要一个关于Borland产品中FPU设置的黑客或一些有用的信息,我可以传递给组件的作者.
有什么我能做的吗?我不认为组件作者有什么需要解决它(通过他的相当无知的回答判断).
我一直在想着安装自己的异常处理程序,我只是在处理程序中重置控制字,并告诉Windows继续执行.我试过安装处理程序SetUnhandledExceptionFilter(),但由于某种原因,没有捕获异常.
我想感谢大家的建议.我已经向作者发送了关于他可以做些什么的说明,以便让我的生活变得更轻松,而不仅仅是我的代码的许多其他客户.我向他建议他应该对FPU控制字进行采样DllMain(DLL_PROCESS_ATTACH),并保存控制字以供日后使用,这样他就可以在调用我的事件处理程序之前重置FPU CW,并从我的调用中返回.
就目前而言,如果有人有兴趣,我会有一个黑客攻击.黑客攻击可能是一个糟糕的,因为我不知道它对他的代码会做什么.我之前收到的确认是他在代码中没有使用任何浮点数,所以这应该是安全的,除非他使用的某些第三方代码依赖于FPU异常.
我对我的应用程序进行的两项修改:
WH_CALLWNDPROC)以捕获绕过消息泵的转角情况在这两种情况下,我都会检查FPU CW是否已更改.如果有,我将其重置为_CW_DEFAULT.
我的老师声称处理器有时可以并行进行FPU操作.像这样:
float a = 3.14;
float b = 5.12;
float c;
float d = 3.02;
float e = 2.52;
float f;
c = a + b;
f = e + d;
Run Code Online (Sandbox Code Playgroud)
所以,正如我所听到的,上面的2个添加操作将比以下更快地执行:
float a = 3.14;
float b = 5.12;
float c;
float d = 3.02;
float e = 2.52;
float f;
c = a + b;
f = c + d;
Run Code Online (Sandbox Code Playgroud)
因为处理器必须等到c计算完成
我想验证这一点,所以我编写了一个执行第二件操作的函数,它通过检查时间戳计数器来测量时间:
flds h # st(7)
flds g # st(6)
flds f # st(5)
flds e …Run Code Online (Sandbox Code Playgroud) 我想知道MXCSR控制寄存器中存储的值的生命周期是什么(包括非正规浮点数的FTZ和DAZ配置):它是在线程的范围内,还是在CPU的所有处理中都很常见/ FPU?
我想知道的是,如果我需要在线程池的每个线程的开头设置它(MXCSR),或者在应用程序中设置一次,或者它会影响应用程序和/或系统中的其他所有内容吗?
谢谢你的帮助!
我试图用c/c ++编译程序,但收到错误信息:
fpu_control.h:没有这样的文件或目录
从谷歌,我发现这个问题是关于浮点精度的处理方式.我读到并非gcc的所有发行版都包含fpu_control.h.
这是我唯一能找到的东西.我已经广泛搜索,找不到任何地方下载这个fpu_control.h.有人可以帮忙吗?
谢谢你们.
我希望在Android上获得最高性能的移动应用程序.我想知道是否有人知道检查手机是否拥有FPU的技巧.
经过一些研究后,似乎FloatMath在拥有FPU的单位上使用类较慢,所以我想拥有两个世界中最好的.
大多数较新的手机都有FPU,但我希望获得该设备可以提供的最高性能.
现代FPU用什么方法来计算超越函数?
例如,英特尔CPU提供指令,例如FSIN,FCOS,FYL2X等我很好奇,什么样的算法将用于实际的硬件实现这些.
我天真的猜测是泰勒系列可能与一些查找表相结合,但这只不过是一个疯狂的猜测.请赐教.
PS这个问题比英特尔硬件更普遍.
在我的大学,我们刚刚介绍了IA32 x87 FPU.但是我们没有被告知如何清除FPU-Stack不再需要的元素.
想象一下,我们正在执行一个简单的计算,如(5.6*2.4)+(3.9*10.3).
.data
value1: .float 5.6
value2: .float 2.4
value3: .float 3.8
value4: .float 10.3
output: .string "The result is: %f\n"
.text
.global main
main:
fld value1 # Load / Push 5.6 into FPU
fmul value2 # Multiply FPU's top (5.6) with 2.4
fld value3 # Load / Push 3.8 into FPU
fmul value4 # Multiply the top element of the FPU's Stacks with 10.3
fadd %st(1) # Add the value under the top element to the top …Run Code Online (Sandbox Code Playgroud) 我必须保持一个双倍值缓存.使用后,它应该无效.两种选择
一种是添加布尔标志,true当缓存值良好时,使用时将其设置为false,当flag为false时,重新计算并重新填充.
第二个更有趣 - 我可以将它保持为double值并使用NaN作为无效/需要重新计算标志.
double get() const {
if (!isnan(_value)) {
double t = _value;
_value = std::numeric_limits<double>::quiet_NaN;
return t;
}
}
Run Code Online (Sandbox Code Playgroud)
对此有何异议?关于效率的任何想法?