Форум: "Начинающим";
Текущий архив: 2018.04.08;
Скачать: [xml.tar.bz2];
ВнизПерегружаемый код Найти похожие ветки
← →
Dmk © (2016-04-11 16:34) [0]Привет! Существует ли такая возможность, чтобы в переменную поместить байт-код и исполнить его? О перегружаемых функциях я знаю - использую. Хочется что то вроде код по выбору:
a := begin b+cy; d*ay; e * ty; end;
или
a := begin b+cx; d*ax; e * tx; end;
а потом Call(a)
← →
Rouse_ © (2016-04-11 16:40) [1]возьми паскальскрипт или LUA и передавай туда все прямо в таком виде, не забывая инициализировать контекст.
← →
Sha © (2016-04-11 17:52) [2]есть же процедурные переменные
← →
Юрий Зотов © (2016-04-11 18:00) [3]Если система допускает исполнение кода в стеке (Win32 допускает), то можно в процедуру передать даже машинный код и выполнить его.
← →
DVM © (2016-04-11 18:00) [4]
> Dmk © (11.04.16 16:34)
> в переменную поместить байт-код
Этот твой код он в виде текста в программу попадает извне?
← →
Dmk © (2016-04-11 18:20) [5]Ищу замену inline asm, только для 64 бит. Не хватает очень. В 32 битах работает, а в 64 - нет. Просто писать кучу разных перегружаемых функций напрягает. У меня получается 4-6 функций, которые делают одно и то же, но код разный: код от Delphi-компилятора, код для MMX, код для SSE, код для SSSE3 и т.д., а там всего то разница в 2-3 строки, которые перегрузить и все.
В inline можно сделать так: db FA,C0, 20, 01, что по сути является исполняемым кодом. Вот и подумалось, что код в переменную загрузить и поменять по ходу исполнения в зависимости от условий.
← →
Dmk © (2016-04-11 18:22) [6]Да и оптимизация кода Delphi-компилятора никакая.
← →
Dmk © (2016-04-11 18:55) [7]И еще inline потом, что лишний call на больших количествах операций сильно заметен.
← →
Rouse_ © (2016-04-11 19:33) [8]
> Dmk © (11.04.16 18:20) [5]
> Ищу замену inline asm, только для 64 бит.
выноси в отдельные функции, целиком написанные на асме и вызывай их.
В чем проблема? Я так и делаю.
← →
Rouse_ © (2016-04-11 19:35) [9]Вот к примеру кусок тебе живого кода:
function ZwQueryInformationProcessEx(
ProcessInformationClass: Integer;
ProcessInformation: Pointer;
ProcessInformationLength: Cardinal): DWORD;
var
SysCallArgument: ULONG_PTR;
aProcessInformationClass: Integer;
aProcessInformation: Pointer;
aProcessInformationLength: Cardinal;
asm
{$IFDEF WIN32}
mov SAVED_EBP, ebp
mov SAVED_ESP, esp
mov aProcessInformationClass, eax
mov eax, ProcessInformation
mov aProcessInformation, eax
mov eax, ProcessInformationLength
mov aProcessInformationLength, eax
mov al, cfNtQueryInformationProcess
call GetSysCallArgument
mov SysCallArgument, eax
push 0
push aProcessInformationLength
push aProcessInformation
push aProcessInformationClass
push $FFFFFFFF
cmp fs:[$C0], 0
jz @32Bit
mov eax, SysCallArgument
lea edx, [esp]
xor ecx, ecx
call RunWow64
jmp @FINALIZE
@32Bit:
push 0
mov eax, SysCallArgument
call RunSysEnter
@FINALIZE:
mov ebp, SAVED_EBP
mov esp, SAVED_ESP
{$ELSE}
mov SAVED_EBP, rbp
mov SAVED_ESP, rsp
sub rsp, $40
mov aProcessInformationClass, ecx
mov aProcessInformation, rdx
mov aProcessInformationLength, r8d
mov rcx, cfNtQueryInformationProcess
call GetSysCallArgument
mov SysCallArgument, rax
or rcx, -1
xor rdx, rdx
mov edx, aProcessInformationClass
mov r8, aProcessInformation
xor r9, r9
mov r9d, aProcessInformationLength
mov qword ptr [rsp+$20], 0
mov rax, SysCallArgument
call RunSysCall
mov rbp, SAVED_EBP
mov rsp, SAVED_ESP
{$ENDIF}
end;
← →
Dmk © (2016-04-11 20:31) [10]Rouse_ © (11.04.16 19:35) [9]
Так я так и делаю. Вот например процедура:function BlendPixelMMX(APixel, AColor: TColorRef; Alpha, Opacity: byte): dword;
const
ShufMask: uint64 = $0100010001000100;
asm
pxor mm0, mm0
pxor mm1, mm1
movq mm2, ShufMask
movd mm4, APixel
punpcklbw mm0, mm4
psrld mm0, 8
movd mm5, AColor
punpcklbw mm1, mm5
psrld mm1, 8
movzx eax, Alpha
inc eax
movzx r11d, Opacity
mul eax, r11d
shr ax, 8
mov dx, ax
xor dx, $FF
inc edx
movd mm3, edx
pshufb mm3, mm2
inc eax
movd mm4, eax
pshufb mm4, mm2
pmullw mm1, mm4
pmullw mm0, mm3
paddusw mm0, mm1
psrlw mm0, 8
packuswb mm0, mm0
movd eax, mm0
end;
Все замечательно, кроме того, что нужна еще такая же на паскале:procedure BlendPixel(dA: TAddress; AColor: TColorRef; Alpha, Opacity: byte);
var
lpAlpha: word;
lpADif: word;
lpBR, lpBG, lpBB: word;
begin
lpAlpha := (((Alpha + 1) * Opacity) shr 8);
lpADif := (lpAlpha xor $FF) + 1;
lpAlpha := lpAlpha + 1;
lpBR := TFColorRef(AColor).r * lpAlpha;
lpBG := TFColorRef(AColor).g * lpAlpha;
lpBB := TFColorRef(AColor).b * lpAlpha;
TFColorRef(PDWord(dA)^).r := ((TFColorRef(PDWord(dA)^).r * lpADif + lpBR) shr 8);
TFColorRef(PDWord(dA)^).g := ((TFColorRef(PDWord(dA)^).g * lpADif + lpBG) shr 8);
TFColorRef(PDWord(dA)^).b := ((TFColorRef(PDWord(dA)^).b * lpADif + lpBB) shr 8);
end;
И тут все замечательно кроме одного - плохой оптимизации. Delphi генерит ужасный код.ScreenBitmap64.pas.353: begin
000000000070DA30 55 push rbp
000000000070DA31 4883EC10 sub rsp,$10
000000000070DA35 488BEC mov rbp,rsp
000000000070DA38 48894D20 mov [rbp+$20],rcx
000000000070DA3C 895528 mov [rbp+$28],edx
000000000070DA3F 44884530 mov [rbp+$30],r8b
000000000070DA43 44884D38 mov [rbp+$38],r9b
ScreenBitmap64.pas.355: lpAlpha := (((Alpha + 1) * Opacity) shr 8);
000000000070DA47 480FB64530 movzx rax,byte ptr [rbp+$30]
000000000070DA4C 83C001 add eax,$01
000000000070DA4F 480FB64D38 movzx rcx,byte ptr [rbp+$38]
000000000070DA54 0FAFC1 imul eax,ecx
000000000070DA57 C1E808 shr eax,$08
000000000070DA5A 6689450E mov [rbp+$0e],ax
ScreenBitmap64.pas.357: lpADif := (lpAlpha xor $FF) + 1;
000000000070DA5E 480FB7450E movzx rax,word ptr [rbp+$0e]
000000000070DA63 6681F0FF00 xor ax,$00ff
000000000070DA68 6683C001 add ax,$01
000000000070DA6C 6689450C mov [rbp+$0c],ax
ScreenBitmap64.pas.359: lpAlpha := lpAlpha + 1;
000000000070DA70 6683450E01 add word ptr [rbp+$0e],$01
ScreenBitmap64.pas.362: lpBR := TFColorRef(AColor).r * lpAlpha;
000000000070DA75 660FB6452A movzx ax,byte ptr [rbp+$2a]
000000000070DA7A 660FAF450E imul ax,[rbp+$0e]
000000000070DA7F 6689450A mov [rbp+$0a],ax
ScreenBitmap64.pas.363: lpBG := TFColorRef(AColor).g * lpAlpha;
000000000070DA83 660FB64529 movzx ax,byte ptr [rbp+$29]
000000000070DA88 660FAF450E imul ax,[rbp+$0e]
000000000070DA8D 66894508 mov [rbp+$08],ax
ScreenBitmap64.pas.364: lpBB := TFColorRef(AColor).b * lpAlpha;
000000000070DA91 660FB64528 movzx ax,byte ptr [rbp+$28]
000000000070DA96 660FAF450E imul ax,[rbp+$0e]
000000000070DA9B 66894506 mov [rbp+$06],ax
ScreenBitmap64.pas.367: TFColorRef(PDWord(dA)^).r := ((TFColorRef(PDWord(dA)^).r * lpADif + lpBR) shr 8);
000000000070DA9F 488B4520 mov rax,[rbp+$20]
000000000070DAA3 488B4D20 mov rcx,[rbp+$20]
000000000070DAA7 480FB64902 movzx rcx,byte ptr [rcx+$02]
000000000070DAAC 0FB7550C movzx edx,word ptr [rbp+$0c]
000000000070DAB0 0FAFCA imul ecx,edx
000000000070DAB3 0FB7550A movzx edx,word ptr [rbp+$0a]
000000000070DAB7 03CA add ecx,edx
000000000070DAB9 C1E908 shr ecx,$08
000000000070DABC 884802 mov [rax+$02],cl
ScreenBitmap64.pas.368: TFColorRef(PDWord(dA)^).g := ((TFColorRef(PDWord(dA)^).g * lpADif + lpBG) shr 8);
000000000070DABF 488B4520 mov rax,[rbp+$20]
000000000070DAC3 488B4D20 mov rcx,[rbp+$20]
000000000070DAC7 480FB64901 movzx rcx,byte ptr [rcx+$01]
000000000070DACC 0FB7550C movzx edx,word ptr [rbp+$0c]
000000000070DAD0 0FAFCA imul ecx,edx
000000000070DAD3 0FB75508 movzx edx,word ptr [rbp+$08]
000000000070DAD7 03CA add ecx,edx
000000000070DAD9 C1E908 shr ecx,$08
000000000070DADC 884801 mov [rax+$01],cl
ScreenBitmap64.pas.369: TFColorRef(PDWord(dA)^).b := ((TFColorRef(PDWord(dA)^).b * lpADif + lpBB) shr 8);
000000000070DADF 488B4520 mov rax,[rbp+$20]
000000000070DAE3 488B4D20 mov rcx,[rbp+$20]
000000000070DAE7 480FB609 movzx rcx,byte ptr [rcx]
000000000070DAEB 0FB7550C movzx edx,word ptr [rbp+$0c]
000000000070DAEF 0FAFCA imul ecx,edx
000000000070DAF2 0FB75506 movzx edx,word ptr [rbp+$06]
000000000070DAF6 03CA add ecx,edx
000000000070DAF8 C1E908 shr ecx,$08
000000000070DAFB 8808 mov [rax],cl
ScreenBitmap64.pas.370: end;
000000000070DAFD 488D6510 lea rsp,[rbp+$10]
000000000070DB01 5D pop rbp
000000000070DB02 C3 ret
← →
Dmk © (2016-04-11 20:34) [11]То что генерит Delphi в 7-8 раз медленней даже MMX версии, я уж не говорю про SSE+++, AVX и т.д.
← →
Rouse_ © (2016-04-11 21:19) [12]Так вот не надо писать на паскале в данном случае
← →
Sha © (2016-04-11 21:25) [13]вот не надо писать на паскале *так* в данном случае )
← →
Dmk © (2016-04-11 21:36) [14]А как надо?
← →
Sha © (2016-04-11 21:47) [15]Можно попробовать что-нибудь вроде этого:
не передавать лишних параметров,
подобрать подходящие типы параметров,
избавиться от лишних переменных,
меньше читать-писать в память,
расположить цвет в 64 битах регистра вразбежку аналогично mmx,
работать в "векторном" стиле сразу с 64 битами,
потом собрать результат.
← →
Dmk © (2016-04-11 21:59) [16]>меньше читать-писать в память,
ВО! Самое то! Delphi почти каждое действие в памяти делает. От того и грустно. Регистры как то побоку. Видимо опять переписывать на asm :(
← →
Sha © (2016-04-11 22:13) [17]Это не Delphi. Вернее, не только Delphi.
Если удастся переписать код в соответствии с [15],
то будет иметь смысл перетащить в процедуру и цикл.
← →
Sha © (2016-04-11 22:28) [18]Поставь себя на место разработчика компилятора.
В твоей процедуре требуется присвоить значение элементу структуры.
Самое простое решение - расположить структуру в памяти и там выполнить присваивание.
Скорее всего ты как разработчик компилятора не стал бы заморачиваться с особым случаем
и анализировать, может ли структура целиком поместиться в регистр,
а затем при помощи масок и сдвигов с учетом выравнивания менять его значение.
Слишком особенный случай, да и не надо это никому.
Поэтому, если хочешь не дергать память на паскале,
то твоя задача как программиста - написать программу без использования структур.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2018.04.08;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.002 c