-
Есть встроенные способы или как то химичить надо? Нужно Self+Offset получить.
-
> Как получить смещение переменной в классе?
Откуда в классе смещения?
-
>Откуда в классе смещения? В адресном пространстве класса :)
Self <- указатель на начало класса. Переменные — адреса после self. Как в record:
lea r9, [self.FClipRegion]
cmp edx, [r9] //rX jl @Out cmp eax, [r9 + 4] //rY jl @Out cmp edx, [r9 + 8] //rEX jg @Out cmp eax, [r9 + 12] //rEY jg @Out
Можно было бы написать класс с функцией OffsetOfVar, но наследников не будет видно. Просто хочу вынести из класса однотипные функции. Self то я передать смогу, а вот смещение компилятор видит только внутри класса. Думал просто встроенные средства есть, а придется опять в обход.
-
> Думал просто встроенные > средства есть, а придется опять в обход.
Откуда им взяться, а главное - зачем ?
-
>а главное - зачем ? Мне для оптимизации надо. Absolute не везде работает.
-
> Мне для оптимизации надо. Absolute не везде работает.
unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
private
FFoo: Integer;
end;
var
Form1: TForm1;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := IntToStr(NativeInt(@TForm1(nil).FFoo));
end;
end. А так - тоже не работает ?
-
>А так - тоже не работает ? Да чего то забылся :) Addr есть же.
Примерно то же самое. Работает.
procedure Test; var hh: double; s: string;
begin hh := 620.343463; P := QWord(Addr(hh)); S := FloatToStrR(PDouble(P)^, 2, false); end;
-
TClass1 = class (TObject) private FN: Integer; public constructor Create(AN: Integer); function GetN: Integer; end;
{ TClass1 }
constructor TClass1.Create(AN: Integer); begin FN := AN; end;
function TClass1.GetN: Integer; asm mov eax, eax.TClass1.FN end;
-
> dmk © (15.08.18 22:24) [4]
Непонятно, чем хак может помочь оптимизации собс-ручно написуемого кода.
-- Regards, LVT.
-
>Непонятно, чем хак может помочь оптимизации >собс-ручно написуемого кода.
Да не хак это. В классе образовалось штук 20 перегружаемых функций (11к строк). Хочется вынести их в inc или в другой модуль, но данные нужны из класса. Для этого нужны глобальные переменные - смещения или лучше прямые адреса. В общем внутри хочется избавиться от зависимости self. На самом деле еще не решил как сделать правильно, поэтому думаю. Вопрос не решен. Кроме того вся эта затея из-за выравнивания переменных на 16. В классе они не выравниваются. Иногда выравниваюся, а иногда выскакивает AV.
Просто для примера:
procedure TBitmap64.SetZPixel64(P: TVertex; dColor: TColorRef); asm .NOFRAME
movq xmm1, qword ptr [P] //Читаем X,Y cvtss2sd xmm0, dword ptr [P + 8] //Конвертируем Z в Double cvtps2dq xmm1, xmm1 //Конвертируем X,Y extractps edx, xmm1, 0 //Извлекаем X extractps eax, xmm1, 1 //Извлекаем Y
imul eax, dword ptr [self.FWidth] //Y в eax add rax, rdx //X в rdx shl rax, 2 mov rdx, rax //Сохраним относительное смещение, чтобы не считать повторно shl rax, 1 add rax, qword ptr [self.FZBufferAddr] //rax = ZAddr
comisd xmm0, [rax] jbe @P ret
@P: movsd [rax], xmm0 add rdx, [self.FMemAddr] mov [rdx], r8d end;
Мне нужны вот эти данные: self.FWidth self.FMemAddr self.FZBufferAddr и еще куча self.Переменных
Просто если я вынесу функции в другой модуль, то откуда мне их брать вне класса? Хочется, чтобы шло обращение к массиву с заранее выравненными переменными. Ибо выравненные переменные иногда до 10% быстрее считаются. 10% в моем случае - это очень хорошо!
-
Просто компилятор знает как посчитать смещения, а я нет. Можно вручную конечно, но это каждый раз заморочка если добавил переменную. Все адреса плывут.
-
> dmk © (28.08.18 14:03) [9]
> Хочется вынести их в inc или в другой модуль, но данные > нужны из класса. > Для этого нужны глобальные переменные - смещения или лучше > прямые адреса. > В общем внутри хочется избавиться от зависимости self.
Что-то всё это выглядит очень запущенным.
Может и не нужны никакие классы? Рекорды тоже можно снабдить методами, ЕМНИП.
Ну, а если уж классы, то сделай им единственное поле в виде рекорда с нужным выравниванием $A.. (хотя, в D32 было максимум 8, а не 16). Т.е., если поле класса одно, то и доступ к нему по одному и тому же смещению.
Вынести же процедуры в другой модуль можно, при условии, что первым параметром в них будет Self.
С простыми структурами (или массивами) возможно, в данном случае, и проще.
-- Regards, LVT.
-
Да с выравниванием я вопрос решил. Просто написал свой класс, который генерит переменные с нужным выравниванием. Правда много ^^^^, но вариантов нет. Если только свой компилятор писать. Не выравнивает дельфи переменные. Только массивы и record'ы.
А смещение я нашел как считать:
type TSomeClass = (TObject) private T: Double; protected public ... end;
var dA, cA, dif: QWord;
procedure CheckOffset; var k: Double;
begin k := PDouble(cA + dif)^; //<--- 1.2 !!! :) end;
procedure TForm.ClassProc; begin T := 1.2; dA := QWord(@T); cA := QWord(Self); dif := (dA - cA);
CheckOffset; end;
-
Выравнивание мне 20 fps добавило.
-
> dmk © (30.08.18 14:58) [12]
> А смещение я нашел как считать:
Если поле в классе одно, то ничего считать и не надо. См., например, [7].
Или так (тоже хак):
type THSomeClass = class (TSomeClass) private ft: Double; end;
sc := TSomeClass.Create; sc.T := 1.2
Далее, в любом месте (в другом модуле) имея sc получаем доступ к полю T путем THClass(sc).ft
-- Regards, LVT.
-
>Если поле в классе одно, то ничего считать и не надо. У меня класс - 3D-объект. Куча полей и переменных. Просто выношу смещения отдельно в константы, а вызов вне класс выглядит так:
procedure LoadColorA(VA: PVertexAttrib); asm .NOFRAME
movd mm7, dword ptr [VA + AT_DC0] // VA = RCX (self) или любой другой указатель end;
В итоге процедура или функция не принадлежит классу, но читает из класса ее переменные. Просто для компактности. Выглядит криво, но удобно с точки зрения использования, т.к. можно вызывать из других классов и компоновать в сборки кода. Иначе приходится плодить однотипные процедуры, которые различаются незначительно и находятся в разных классах.
|