go cmd/compile: 在比较字符串常量时,将整数测试组合在一起,

c9qzyr3d  于 10个月前  发布在  Go
关注(0)|答案(6)|浏览(84)

为了与"abc"进行比较,我们目前会发出代码来测试uint16(前两个字节)是否等于uint16("ab"),然后检查第三个字节是否等于"c"。
我怀疑将这三个字节加载到uint32的前三个字节中(两个加载操作结合|)会更高效,然后将其与uint32("abc\0")进行比较。
我不确定我们是否可以使用比较组合重写规则来实现这一点(请注意,通常加载操作会产生副作用,但在这个例子中,我们确信它们不会导致故障),或者是否最好在生成此优化的walk.go文件中修复它。
低优先级。

fgw7neuy

fgw7neuy1#

cc @mundaym,他一直在思考如何将分支合并到SSA规则中。

qcuzuvrc

qcuzuvrc2#

棘手的一个问题。这种转换可能会减慢/膨胀一些代码(通常当 uint16(first two bytes)==uint16("ab") 不太可能时),所以虽然我认为后端可以做到,但我不确定它是否应该这样做,除非它有类似的可能性信息。

请注意,对于较长的字符串,我们可以重叠负载,因为它们本来就是不对齐的(不确定我们是否已经这样做了 - 我并不认为我们在我看到的 walk 中这样做):

  1. x == "abcdefg" -> x[0:4] == "abcd" && x[3:7] == "defg"

我认为这种转换可以贪婪地应用,因为它不会向“未采用”路径添加任何额外的指令。它还可以应用于任何我们想要检查字符串最后3个字符的情况,并且我们也知道字符串的长度大于3(即我们可以在字符串中访问索引-1并在边界内)。我怀疑这偶尔会在字符串 switch 语句降低中出现。即使已知要避免在竞争性代码中出现双重加载相关问题,重叠的字符也可以被掩盖。话虽如此,这在 SSA 中都会非常困难,但也许字符串比较降低可以做到这一点。

cedebl8k

cedebl8k3#

重叠负荷是个好主意,谢谢!我们应该在步行时进行。

l3zydbqr

l3zydbqr4#

我刚刚(模糊地)想起几年前,由于它们干扰了加载-存储转发,重叠负载导致了性能问题。

bjp0bcyl

bjp0bcyl5#

我刚刚(模糊地)想起几年前,由于它们干扰了load-store forwarding,重叠负载导致了性能问题。
是的,这可能是一个问题。尽管Go程序不太倾向于按值复制字符串,因此我们可能不会经常看到load-hit-store hazards。我的猜测是,当我们比较它们时,字符串很少仍然在存储缓冲区中,但这只是我的猜测。

hujrc8aj

hujrc8aj6#

这也适用于整数小数组的比较;参见walkcompare。

相关问题