Я пытался запустить следующую,Как использовать SSE с выравниванием данных в Delphi XE3?
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;
Это дает нарушение прав доступа на MOVAPS, насколько я знаю, MOVAPS можно доверять, если ячейка памяти 16 выравнивания. Это не проблема, если movups (выравнивание не требуется).
Так что мой вопрос в Delphi XE3, {$ CODEALIGN}, похоже, не работает в этом случае.
EDIT
Очень странно ... Я пробовал следующее.
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.
Если «использовать окна» не добавлены, все в порядке. Если «использовать окно», то оно выкинет исключение в c: = add4 (a, b), но не в test().
Кто может это объяснить?
EDIT все это имеет смысл для меня, теперь. выводы для Delphi XE3 - 64-разрядные
- кадры стека на X64 установлены в 16 байт (при необходимости), {$ CODEALIGN 16} выравнивает код для Proc/удовольствия до 16 байт.
- динамический массив живет в куче, который может быть установлен для выравнивания 16, используя SetMinimumBlockAlignment (mba16byte)
- однако, стек вары не всегда 16 байт выровнены, например, если вы объявить целочисленный вар перед v1 , v2 в приведенном выше примере, например test(), пример не будет работать.
'CODEALIGN' выравнивает _code_. Если вы хотите выровнять _data_, вы можете использовать директиву 'ALIGN'. – Michael
Я тоже пытался {$ ALIGN 16}, и он не работает. –