【问题标题】:How can I get SSE rounding in a Delphi version prior to XE2?如何在 XE2 之前的 Delphi 版本中获得 SSE 舍入?
【发布时间】:2012-10-08 13:22:06
【问题描述】:

如何在以前的 Delphi 版本中获得 XE2 风格的舍入,所以使用 SSE ?

【问题讨论】:

  • 我不明白这个问题。 XE2 发生了什么变化?
  • SSE 舍入。但我要求这个分享我的知识,(我已经编辑了标题。)
  • SO 的这个特性不需要测试。众所周知,它可以工作。你仍然应该遵守什么是好问题的准则。请适当地编辑问题。
  • @Tony 如果您正在编写浮点密集型代码,那么包括定制 asm 可能是值得的。显然有一个权衡,但是如果您的客户希望您的程序运行得更快,并且使用 asm 可以使其运行得更快,那么权衡是值得的。我在我的应用程序中使用了很多定制的 x87 asm。它提供了大约 5% 的加速。不多。但是,它也不会花费我,因为它永远不会改变。算术就是这样。一旦你做对了,你永远不需要改变它。
  • 请重新表述您的问题,以便更清楚您的目标。诸如:为什么 SSE 舍入很重要?它与以前的 Delphi 版本中的舍入有何不同?

标签: delphi rounding delphi-2007 sse


【解决方案1】:

内联 Delphi 程序集支持 SSE 指令已有一段时间了。 两种重载版本是可能的:单和双。 此外还有两个版本:作为参数输入或作为指针输入。 这个版本比原生 Round()/Trunc() 方法特别快。

圆你有:

Function RoundSSE(Value: Single): Integer; Overload;
Asm
  // additional PUSH/POP pointer stack added automatically
  CVTSS2SI  EAX, Value
End;

Function RoundSSE(Value: Double): Integer; Overload;
Asm
  // additional PUSH/POP pointer stack added automatically
  MOVQ      XMM0,Value
  CVTSD2SI  EAX, XMM0
End;

Function RoundMEM_SSE(Var Value: Single): Integer; Overload;
Asm
  // as written, fatest version
  CVTSS2SI  EAX, [Value]
End;

Function RoundMEM_SSE(Var Value: Double): Integer; Overload;
Asm
  // as written, fatest version
  CVTSD2SI  EAX, [Value]
End;

要截断您与 CVTTSS2SI / CVTTSD2SI 相同:

Function TruncSSE(Value: Single): Integer; Overload;
Asm
  // additional PUSH/POP pointer stack added automatically
  CVTTSS2SI  EAX, Value
End;

Function TruncSSE(Value: Double): Integer; Overload;
Asm
  // additional PUSH/POP pointer stack added automatically
  MOVQ      XMM0,Value
  CVTTSD2SI  EAX, XMM0
End;

Function TruncMEM_SSE(Var Value: Single): Integer; Overload;
Asm
  // as written, fatest version
  CVTTSS2SI  EAX, [Value]
End;

Function TruncMEM_SSE(Var Value: Double): Integer; Overload;
Asm
  // as written, fatest version
  CVTTSD2SI  EAX, [Value]
End;

到 Floor, Ceil,分别使用 *TruncMEM_SSE(value)* 和 RoundSSE(value + 0.5)。 这些功能将为您带来 20% 的性能增益。它已经在 循环和实际程序中(填充内存缓存/填充指令缓存,因此可以将其视为实际测试)。

【讨论】:

  • 鉴于我想要精确到 x 位小数,我为什么要使用单打和双打???
  • 在我的简单基准测试中,双精度 RoundSSE 比 RTL 的 Round 慢 3 倍。这当然适用于 32 位代码。我正在使用 XE2。使用默认项目的 Release 构建选项。
  • @az01 那有什么意义呢?我可以很快得到不准确的结果,不禁感到,但你已经跌跌撞撞地直接进入了这个太聪明的领域。如果我开始在代码库中间敲打汇编,我可以想象我的同事会不满,一点也不漂亮。
  • 现在,你在这个帖子中斥责我并称我为“愚蠢”。在我的试验中使用 XE2 32 位。它与 Delphi 2010 甚至 Delphi 6 具有相同的运行时性能。如果有任何愚蠢之处,那不是我使用 XE2。在一条被删除的评论中,你说“你为什么很烂?”好吧,我想我不会。你需要照照镜子,考虑一下你的态度。这样的说法是绝对不能接受的。
  • 最后,我在这个帖子中学到了一些有用的东西。也就是说,用于舍入的 SSE 指令比 x87 指令快一点,但是 32 位编译器的 8 字节实数 ABI 使得利用它变得很尴尬。所以谢谢你给我学习的机会。我一直很感激。我相信你已经知道这些细节了。很遗憾你没有在问答中清楚地阐明它们。 Q 需要准确地陈述问题。 A 需要包含更多细节和基准。这可能是一个很好的问答,但目前缺乏。
猜你喜欢
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多