如何在Delphi XE3中使用align-data-move SSE?

jus*_*tyy 7 delphi assembly sse basm

我试图运行以下,

type
  Vector = array [1..4] of Single;

{$CODEALIGN 16}
function add4(const a, b: Vector): Vector; register; assembler;
asm
  movaps xmm0, [a]
  movaps xmm1, [b]
  addps xmm0, xmm1
  movaps [@result], xmm0
end;
Run Code Online (Sandbox Code Playgroud)

它提供了对movaps的访问冲突,据我所知,如果内存位置为16对齐,则可以信任movaps.如果movups(不需要对齐),它没有问题.

所以我的问题是,在Delphi XE3中,{$ CODEALIGN}在这种情况下似乎不起作用.

编辑

很奇怪......我尝试了以下几点.

program Project3;

{$APPTYPE CONSOLE}

uses
  windows;  // if not using windows, no errors at all

type
  Vector = array [1..4] of Single;

function add4(const a, b: Vector): Vector;
asm
  movaps xmm0, [a]
  movaps xmm1, [b]
  addps xmm0, xmm1
  movaps [@result], xmm0
end;

procedure test();
var
  v1, v2: vector;
begin
  v1[1] := 1;
  v2[1] := 1;
  v1 := add4(v1,v2);  // this works
end;

var
  a, b, c: Vector;

begin
  {$ifndef cpux64}
    {$MESSAGE FATAL 'this example is for x64 target only'}
  {$else}
  test();
  c := add4(a, b); // throw out AV here
  {$endif}
end.
Run Code Online (Sandbox Code Playgroud)

如果没有添加"使用窗口",一切都很好.如果'使用窗口',那么它将在c:= add4(a,b)但不在test()中抛出异常.

谁能解释一下?

编辑 它现在对我来说都很有意义.Delphi XE3的结论 - 64位是

  1. X64的堆栈帧设置为16字节(根据需要),{$ CODEALIGN 16}将proc/fun的代码与16字节对齐.
  2. 动态数组存在于堆中,可以使用SetMinimumBlockAlignment(mba16byte)将其设置为对齐16
  3. 但是,堆栈变量并不总是16字节对齐,例如,如果在上例中的v1,v2之前声明一个整数变量,例如test(),则该示例将不起作用.

Dav*_*nan 4

您需要数据按 16 字节对齐。这需要一些照顾和关注。您可以确保堆分配器与 16 字节对齐。但是您无法确保编译器会对堆栈分配的变量进行 16 字节对齐,因为您的数组的对齐属性为 4,即其元素的大小。在其他结构内声明的任何变量也将具有 4 字节对齐。这是一个很难清除的障碍。

我认为您无法在当前可用的编译器版本中解决您的问题。至少不会,除非你放弃堆栈分配的变量,我猜这是一颗难以下咽的药丸。您可能会幸运地使用外部汇编器。