Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly asm(fpu)规范化-如何优化它_Assembly_X86_Sse_Fpu - Fatal编程技术网

Assembly asm(fpu)规范化-如何优化它

Assembly asm(fpu)规范化-如何优化它,assembly,x86,sse,fpu,Assembly,X86,Sse,Fpu,我已经编写了一些x86 asm-fpu例程 规范化一个由三个浮点数组成的向量-就是这样 _asm_normalize10:; Function begin push ebp ; 002E _ 55 mov ebp, esp ; 002F _ 89. E5 mov eax, dword [ebp+8H]

我已经编写了一些x86 asm-fpu例程 规范化一个由三个浮点数组成的向量-就是这样

    _asm_normalize10:; Function begin
    push    ebp                                     ; 002E _ 55
    mov     ebp, esp                                ; 002F _ 89. E5
    mov     eax, dword [ebp+8H]                     ; 0031 _ 8B. 45, 08
    fld     dword [eax]                             ; 0034 _ D9. 00
    fmul    st0, st(0)                              ; 0036 _ DC. C8
    fld     dword [eax+4H]                          ; 0038 _ D9. 40, 04
    fmul    st0, st(0)                              ; 003B _ DC. C8
    fld     dword [eax+8H]                          ; 003D _ D9. 40, 08
    fmul    st0, st(0)                              ; 0040 _ DC. C8
    faddp   st1, st(0)                              ; 0042 _ DE. C1
    faddp   st1, st(0)                              ; 0044 _ DE. C1
    fsqrt                                           ; 0046 _ D9. FA
    fld1                                            ; 0048 _ D9. E8
    fdivrp  st1, st(0)                              ; 004A _ DE. F1
    fld     dword [eax]                             ; 004C _ D9. 00
    fmul    st(0), st1                              ; 004E _ D8. C9
    fstp    dword [eax]                             ; 0050 _ D9. 18
    fld     dword [eax+4H]                          ; 0052 _ D9. 40, 04
    fmul    st(0), st1                              ; 0055 _ D8. C9
    fstp    dword [eax+4H]                          ; 0057 _ D9. 58, 04
    fld     dword [eax+8H]                          ; 005A _ D9. 40, 08
    fmulp   st1, st(0)                              ; 005D _ DE. C9
    fstp    dword [eax+8H]                          ; 005F _ D9. 58, 08
    pop     ebp                                     ; 0062 _ 5D
    ret                                             ; 0063 _ C3
    ; _asm_normalize10 End of function
[这是我的代码;-)它可以工作,并且经过我的测试]

我对x86汇编不太了解,我想找一些 优化上述(纯fpu旧asm,尤其是不带sse) 但要比上面优化一些)

特别是,我想知道上面的代码是否有些蹩脚: 我在fpu堆栈上加载x y z向量,然后计数1/sqrt(x*x+y*y+z*z) 然后再次从ram中加载x y z并乘以值,然后存储-

这是次优化吗?我应该只加载一次x y z(而不是两次)
然后将其保持在fpu堆栈计数上,然后在末尾存储?

您可以完全按照您的建议执行,并且只加载一次
x
y
z
。这似乎是有帮助的。除此之外,假设你仍然不想使用近似平方根逆技巧,我看不出有什么机会

未测试:

; load everything
fld dword [eax]
fld dword [eax+4]
fld dword [eax+8]
; square and add
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 1 for fpu stack)
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 2 for fpu stack)
faddp st(1), st(0)
                  ; (see diagram 3 for fpu stack)
fld st(1)
fmul st(0), st(0)
faddp st(1), st(0)
                  ; (see diagram 4 for fpu stack)
; calculate inverse sqrt
fsqrt
fld1
fdivrp st(1), st(0)
; scale
fmul st(1), st(0)
fmul st(2), st(0)
fmulp st(3), st(0)
; store
fstp dword [eax+8]
fstp dword [eax+4]
fstp dword [eax]
图1:

st3: x
st2: y
st1: z
st0: x * x
图2:

st4: x
st3: y
st2: z
st1: x * x
st0: y * y
图3:

st3: x
st2: y
st1: z
st0: x * x + y * y
图4:

st3: x
st2: y
st1: z
st0: x * x + y * y + z * z

您可以完全按照您的建议执行并只加载一次
x
y
z
。这似乎是有帮助的。除此之外,假设你仍然不想使用近似平方根逆技巧,我看不出有什么机会

未测试:

; load everything
fld dword [eax]
fld dword [eax+4]
fld dword [eax+8]
; square and add
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 1 for fpu stack)
fld st(2)
fmul st(0), st(0)
                  ; (see diagram 2 for fpu stack)
faddp st(1), st(0)
                  ; (see diagram 3 for fpu stack)
fld st(1)
fmul st(0), st(0)
faddp st(1), st(0)
                  ; (see diagram 4 for fpu stack)
; calculate inverse sqrt
fsqrt
fld1
fdivrp st(1), st(0)
; scale
fmul st(1), st(0)
fmul st(2), st(0)
fmulp st(3), st(0)
; store
fstp dword [eax+8]
fstp dword [eax+4]
fstp dword [eax]
图1:

st3: x
st2: y
st1: z
st0: x * x
图2:

st4: x
st3: y
st2: z
st1: x * x
st0: y * y
图3:

st3: x
st2: y
st1: z
st0: x * x + y * y
图4:

st3: x
st2: y
st1: z
st0: x * x + y * y + z * z

代码是这样的,只写一次,从不读。任何调试器显示操作码,都不会自动生成好的注释。考虑一个赏金,让用户花时间来逆向工程。你错了,它显然被铭记,虽然ASM知识是需要的代码,就像这是写一次,从不读。任何调试器显示操作码,都不会自动生成好的注释。考虑一个赏金,让用户花时间来逆向工程。你错了,它被简单地铭记,虽然ASM知识是必需的,我会测试它。我不知道fld st(2)助记符。您是否知道一种只从(fpu)堆栈获取(pop)编号的方法(无需其他操作)?至于“carmack’s”技巧,我测量了它,这是85个周期(在c中,不是asm测试),所以稍微快一点(可能重新编写为asm,它会更快),将尝试它l8er-也将返回到前面提到的RaySphereIntersection例程和sse-但后来(还没有到那里)TNxmuch@grungefightr你这是什么意思“仅从S堆栈中获取编号”?已编辑。我的意思是pop,一些代码我试图在没有其他操作的情况下编写所需的pop(如stp-仅pop而不存储;-)@Grungfightr
fstp st(0)
pops一个,您可以使用
fcompp
弹出两个(更改fpu条件代码,但它们很少使用)@Grungfightr它存储到条目中,然后它会弹出,所以这不是问题。TNX,我会测试它。我不知道fld st(2)助记符。你知道可能有一种方法只从(fpu)堆栈中获取(pop)数字(没有其他操作)?至于“carmack”技巧,我测量了它,这是85个周期(在c中,没有经过asm测试),所以稍微快一点(可能重新编写为asm会更快),将尝试l8er-也将返回到之前提到的RaySphereIntersection例程和sse-但后来(尚未到达)TNxmuch@grungefightr“仅从堆栈中获取数字”是什么意思?已编辑。我是指pop,一些代码我试图在没有其他操作的情况下编写所需的pop(如stp-仅弹出而不存储;-)@Grungfightr
fstp st(0)
pops one,您可以使用
fcompp
弹出两个(更改fpu条件代码,但它们很少被使用)。@Grungfightr它存储到条目,然后无论如何弹出,所以这不是问题。