gpt4 book ai didi

delphi - 使用 SSE2 在 Delphi 中内联汇编低效程序

转载 作者:行者123 更新时间:2023-12-03 18:14:59 25 4
gpt4 key购买 nike

我有一个简单的基于浮点的操作,它总是执行两次。所以我试图将它翻译成 SSE,但它只是失败了。高级语言是Delphi,不支持Intrinsics函数,只好自己写。基本上我只有参数加载/卸载和一些乘法和加法。:

Procedure TLP1Poly2.Process(Const _a1, _b1, _OldIn1, _OldIn2, _OldOut1, _OldOut2:     Double; Var Sample1, Sample2: Double);
Asm
MOVLPD XMM4, _a1
MOVHPD XMM4, _a1
MOVLPD XMM3, _b1
MOVHPD XMM3, _b1
//
MOVLPD XMM0, [Sample1]
MOVHPD XMM0, [Sample2]
MULPD XMM0, XMM4
//
MOVLPD XMM1, _OldIn1
MOVHPD XMM1, _OldIn2
MULPD XMM1, XMM4
//
MOVLPD XMM2, _OldOut1
MOVHPD XMM2, _OldOut2
MULPD XMM2, XMM3
//
ADDPD XMM0, XMM1
ADDPD XMM0, XMM2
//
MOVLPD [Sample1], XMM0
MOVHPD [Sample2], XMM0
//
// which stands for twice this:
// Sample:= Sample*a1 + oldinp*a1 + oldout*b1;
//
End;

但此过程不起作用,如果我“nop”Sample1/Sample2 加载/保存之间的所有内容,则没问题,但否则我的过滤器将保持静音。在这方面我没有得到 SSE 的基本内容是什么?

附录:

旧类(class):

constructor TLP1.create;
begin
oldfreq := -1 ;
end;
procedure TLp1.process(inp,Frq,SR :single);
begin
if Frq<>oldfreq then
begin
a := 2* SR;
t := Frq * _ppi;
n := 1/ (a+t) ;
b1:= (a - t) * n;
a1:= t * n;
oldfreq := frq;
end;
outlp := (inp+_kd)*a1 + oldinp*a1 + oldout*b1;
oldout := outlp ;
oldinp := inp;
end;

新类(class):

Procedure TLP2Poly2.SetSamplerate(Const Value: Single);
Begin
If Value = FSamplerate Then Exit;
FSamplerate := Value;
UpdateCoefficients;
End;

Procedure TLP2Poly2.SetFrequency(Const Value: Single);
Begin
If Value = FFrequency Then Exit;
FFrequency := Value;
UpdateCoefficients;
End;

Procedure TLP2Poly2.UpdateCoefficients;
Var
a,t,n: Single;
Begin
a := 2 * FSamplerate ;
t := FFrequency * 2 * pi;
n := 1/ (a+t) ;
b1:= (a - t) * n;
a1:= t * n;
End;

Procedure TLP2Poly2.Process(Var Sample1, Sample2: Double);
Var
o1, o2: Double;
Begin
o1 := Sample1;
o2 := Sample2;
IntProcess( a1, b1, OldIn1, OldIn2, OldOut1, OldOut2, Sample1, Sample2);
OldOut1 := Sample1;
OldOut2 := Sample2;
OldIn1 := o1;
OldIn2 := o2;
End;

Procedure TLP2Poly2.IntProcess(Const _a1, _b1, _OldIn1, _OldIn2, _OldOut1, _OldOut2: Double; Var Sample1, Sample2: Double);
Asm
MOVLPD XMM4, _a1
MOVHPD XMM4, _a1
MOVLPD XMM3, _b1
MOVHPD XMM3, _b1
//
MOVLPD XMM0, [Sample1]
MOVHPD XMM0, [Sample2]
MULPD XMM0, XMM4
//
MOVLPD XMM1, _OldIn1
MOVHPD XMM1, _OldIn2
MULPD XMM1, XMM4
//
MOVLPD XMM2, _OldOut1
MOVHPD XMM2, _OldOut2
MULPD XMM2, XMM3
//
ADDPD XMM0, XMM1
ADDPD XMM0, XMM2
//
MOVLPD [Sample1], XMM0
MOVHPD [Sample2], XMM0
End;

最佳答案

在为 Delphi 编写汇编程序时,尤其是在 64 位模式下,您应该始终了解参数的传递方式。我从不使用前 4 个参数的名称,因为它们无论如何都在寄存器中。我直接使用这些寄存器。

请注意,_a1_b1_oldIn1_oldIn2 是在 XMM0 - XMM3 分别,因此您的代码的第一部分会覆盖其中一些寄存器。例如,使用 _b1 加载 XMM3 会覆盖 _oldIn2XMM2 也是如此,它包含 _oldIn1

重新安排您的寄存器使用是有意义的,这样您就不必使用内存存储作为中间。

IOW,尝试类似(未经测试)的方法:

asm
MOVDDUP XMM0,XMM0
MOVDDUP XMM1,XMM1

MOVLPD XMM4,[Sample1]
MOVHPD XMM4,[Sample2]
MULPD XMM4,XMM0

// etc...

关于delphi - 使用 SSE2 在 Delphi 中内联汇编低效程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7909130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com