Альтернатива ручному исправлению выравнивания данных sse2 на 16-байтовой границе - PullRequest
2 голосов
/ 23 февраля 2012

Есть ли альтернатива следующему исправлению вручную:

// excerpt adapted from SIMDTest in   
// http://www.mccauslandcenter.sc.edu/mricro/obsolete/graphics/simdtest.zip
//
var
  lAdblRAp, lArraySz, lAdblRA, Doublep: LongInt;
begin
  // ...
  GetMem(lAdblRAp,(lArraySz * SizeOf(Double)) + 32);
  lAdblRA := Doublep((Integer(lAdblRAp) and $FFFFFFF0) + 16);
  // ...
end;

Обратите внимание, что этот фрагмент кода встроен либо в процедуру, либо в функцию.

Ответы [ 2 ]

3 голосов
/ 23 февраля 2012

Стандартный способ - использовать диспетчер памяти, который будет выравнивать блоки по 16-байтовым границам.FastMM сделает это, но вам нужна полная версия, чтобы настроить эту опцию.

Обратите также внимание, что код в вашем вопросе не готов к 64 битам, так как он приводит указатель к 4-байтовому целому числу.

2 голосов
/ 23 февраля 2012

Если вы используете новые версии Delphi (я тестировал с XE и XE2), лучший и самый простой способ - это вызвать SetMinimumBlockAlignment(mba16Byte) на первом месте в вашем коде.

Затем вызвать обычныйGetMem, New или любую функцию выделения памяти и убедитесь, что адрес выровнен по 16-байтовым границам

Редактировать:

Также, если вы предпочитаете использовать ручнойИсправьте, лучший эффективный способ, который тратит меньше памяти, заключается в следующем:

var
  lArraySz: LongInt;
  lAdblRAp, lAdblRA: Pointer;     

begin
  // ...
  GetMem(lAdblRAp,(lArraySz * SizeOf(Double)) + 16);
  lAdblRA := Pointer((Integer(lAdblRAp) + 15) and $FFFFFFF0));
  // ...
end;

Он будет использовать на 16 байт меньше для каждого выделения.

...