-2

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

4

1 回答 1

2

内联 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% 的性能增益。它已经在循环和实际程序中进行了测试(填充了内存缓存/填充了指令缓存,因此可以将其视为真实测试)。

于 2012-10-08T13:22:06.913 回答