请注意,cmplx.Inf被列为位于$GOROOT/src/math/bits.go中。看起来cmd/objdump可能假设函数中的第一个指令位于函数内。在没有前导码的函数中,至少这个假设是错误的。另外,为什么那里有内联标记?cc @randall77,因为这是inlmarks的意外后果cc @dr2chase,用于所有与位置相关的事情
cmplx.Inf
$GOROOT/src/math/bits.go
smdncfj31#
https://golang.org/cl/182758提到了这个问题:cmd: Correctly report the source file of an assembly
cmd: Correctly report the source file of an assembly
9lowa7mx2#
感谢Josh的所有帮助。
kmynzznz3#
在genssa之前,我们有:
v8 (+21) = InlMark <void> [1] v1 v19 (+17) = InlMark <void> [2] v1 v14 (22) = MOVSDconst <float64> [+Inf] : X0
在genssa之后,我们有:
v8 00006 (?) NOP v19 00007 (+17) XCHGL AX, AX v14 00008 (+21) MOVSD $(+Inf.0), X0
是的,内联标记移除有些奇怪,可能需要修复。不知何故,它没有移除两个标记,而是将一个合并成一个实际的指令(v8->v14),也许这迫使它保留另一个标记(v19)?我并不惊讶的主要错误。除了第一个指令之外,没有其他地方可以获取位置信息。也许还有返回指令(如果有的话)?
1aaf6o9v4#
另一个寻找位置信息的地方,至少在amd64上,是任何尾随(填充)INT $3指令。但是将启发式更改为首先查找RET,然后查看第一个指令(如果没有RET),似乎是个好开始。
lawou6xi5#
你好,我是Joshua,对于这个程序还有很多不懂的地方。
在第186行的Print方法中:
由于传递给Decode的回调函数中调用了Fprintf,所以我使用了额外的一个tabWriter示例。封闭的Print方法依赖于io.Writer接口,因此更改比我想要深入讨论的要复杂得多。请告诉我上面的解释是否合理,或者我应该采取什么方向来修复这个问题。
mnowg1ta6#
感谢您关注这个问题!如果简单地调用两次Decode,首先只是为了找到RET(如果有的话),然后第二次进行所有打印,性能会受到影响吗?(顺便说一下,函数中的任何RET都可以工作。它不一定是最终指令,而且通常不会是。)
brgchamk7#
这是一个更好的建议。它减少了更改的行数,并保留了输出的顺序以匹配代码中的逻辑顺序。感谢指出RET代码可能在指令中的任何位置,我过于关注示例,没有考虑到这一点。一个警告是,我不确定如何短路调用Decode,因为函数正在执行一个回调,这可能会阻止添加goto标签,因为作用域?执行时间是线性的,所以我不认为解码符号两次会增加太多开销,除非有我不知道的低级事件发生。我会添加一些性能分析代码,并对算法进行一些性能测试,因为这将是一个很好的学习经验。
v9tzhpje8#
听起来不错。如果需要帮助,请告诉我。
关于短路问题,我认为你需要添加对它的显式支持,例如让Decode函数的arg返回一个布尔值,表示是否停止解码。你可以先不加这个功能,作为第二步再加上,因为这是一个优化。
lsmd5eda9#
今天早上,我熟悉了pprof。当调用函数两次以获取返回代码时,会出现2倍的减速。添加短路逻辑并在运行时重新运行分析。这将减少额外开销的一半,这可能接近平均情况。我有一台快速的笔记本电脑,但结果可以在几秒钟内测量到,这足以证明包含短路逻辑是合理的,因为它已经写下来了。我将提交这些更改,并将其留给代码审查。
9条答案
按热度按时间smdncfj31#
https://golang.org/cl/182758提到了这个问题:
cmd: Correctly report the source file of an assembly
9lowa7mx2#
感谢Josh的所有帮助。
kmynzznz3#
在genssa之前,我们有:
在genssa之后,我们有:
是的,内联标记移除有些奇怪,可能需要修复。不知何故,它没有移除两个标记,而是将一个合并成一个实际的指令(v8->v14),也许这迫使它保留另一个标记(v19)?
我并不惊讶的主要错误。除了第一个指令之外,没有其他地方可以获取位置信息。也许还有返回指令(如果有的话)?
1aaf6o9v4#
另一个寻找位置信息的地方,至少在amd64上,是任何尾随(填充)INT $3指令。但是将启发式更改为首先查找RET,然后查看第一个指令(如果没有RET),似乎是个好开始。
lawou6xi5#
你好,我是Joshua,对于这个程序还有很多不懂的地方。
在第186行的Print方法中:
由于传递给Decode的回调函数中调用了Fprintf,所以我使用了额外的一个tabWriter示例。封闭的Print方法依赖于io.Writer接口,因此更改比我想要深入讨论的要复杂得多。请告诉我上面的解释是否合理,或者我应该采取什么方向来修复这个问题。
mnowg1ta6#
感谢您关注这个问题!
如果简单地调用两次Decode,首先只是为了找到RET(如果有的话),然后第二次进行所有打印,性能会受到影响吗?(顺便说一下,函数中的任何RET都可以工作。它不一定是最终指令,而且通常不会是。)
brgchamk7#
这是一个更好的建议。它减少了更改的行数,并保留了输出的顺序以匹配代码中的逻辑顺序。感谢指出RET代码可能在指令中的任何位置,我过于关注示例,没有考虑到这一点。
一个警告是,我不确定如何短路调用Decode,因为函数正在执行一个回调,这可能会阻止添加goto标签,因为作用域?
执行时间是线性的,所以我不认为解码符号两次会增加太多开销,除非有我不知道的低级事件发生。我会添加一些性能分析代码,并对算法进行一些性能测试,因为这将是一个很好的学习经验。
v9tzhpje8#
听起来不错。如果需要帮助,请告诉我。
关于短路问题,我认为你需要添加对它的显式支持,例如让Decode函数的arg返回一个布尔值,表示是否停止解码。你可以先不加这个功能,作为第二步再加上,因为这是一个优化。
lsmd5eda9#
今天早上,我熟悉了pprof。当调用函数两次以获取返回代码时,会出现2倍的减速。添加短路逻辑并在运行时重新运行分析。这将减少额外开销的一半,这可能接近平均情况。我有一台快速的笔记本电脑,但结果可以在几秒钟内测量到,这足以证明包含短路逻辑是合理的,因为它已经写下来了。我将提交这些更改,并将其留给代码审查。