gpt4 book ai didi

go - 使用 FlatBuffers 更快地发送/写入 Float32 数组

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

我正在使用flatbuffers在 Go 中通过 TCP 在本地计算机上的两个端口之间发送 10000 个 float 组。我在循环中发送相同的消息,仅执行此操作。我实现的速率仅为每条消息大约 2 毫秒,但在 C++ 中,我实现的每条消息大约为 140 微秒。我的 FlatBuffers 消息有以下架构

namespace MyModel;

table Features {
data:[float32];
}

root_type Features;

然后在 Go 代码中我有 builder := flatbuffers.NewBuilder(1024)conn, err := net.Dial("tcp", endPoint)然后在发送循环中进行了一些其他操作之后:

builder.Reset()

MyModel.FeaturesStartDataVector(builder, nFloat32s)
for i := nFloat32s - 1; i >= 0; i-- {
builder.PrependFloat32(data[i])
}
featuresData := builder.EndVector(nFloat32s)
MyModel.FeaturesStart(builder)
MyModel.FeaturesAddData(builder, featuresData)
features := MyModel.FeaturesEnd(builder)

builder.Finish(features)
msg := builder.FinishedBytes()
msgLen := make([]byte, 4)
flatbuffers.WriteUint32(msgLen, uint32(len(msg)))

conn.Write(msgLen)
conn.Write(msg)

接收到的消息数量及其内容与 Python 程序接收到的消息一样正确。但它比我使用 C++ 发送器进行基准测试时慢 14 倍,并且数据也由同一 Python 程序接收。我正在使用nFloats = 100000

分析显示 PrependFloat32 花费了大量时间。

(pprof) top5 -cum
Showing nodes accounting for 2850ms, 61.29% of 4650ms total
Dropped 5 nodes (cum <= 23.25ms)
Showing top 5 nodes out of 18
flat flat% sum% cum cum%
0 0% 0% 4600ms 98.92% main.main
550ms 11.83% 11.83% 4600ms 98.92% main.run
0 0% 11.83% 4600ms 98.92% runtime.main
1140ms 24.52% 36.34% 3640ms 78.28% github.com/google/flatbuffers/go.(*Builder).PrependFloat32
1160ms 24.95% 61.29% 1790ms 38.49% github.com/google/flatbuffers/go.(*Builder).Prep

我可以让它更快吗?

(当然,对于这样的平面数据,我可以只使用原始套接字,但稍后我将使消息变得更加复杂。)

最佳答案

对于任何对 linked github code 中的解决方案感到好奇的人从snow_abstraction的评论来看,问题使用:

    for i := nFloat32s - 1; i >= 0; i-- {
builder.PrependFloat32(data[i])
}

与链接代码相比:

    for i := nFloat32s - 1; i >= 0; i-- {
builder.PlaceFloat32(data[i])
}

PlaceFloat32 速度更快,因为:“MyModel.FeaturesStartDataVector 分配了足够的空间,因此可以跳过惯用调用 build.PrependFloat32(data[i]) 所需的额外检查。”

flatbuffers source code确认 PrependFloat32 调用 Prep 进行一些对齐和大小检查,这似乎是多余的,因为之前调用了 MyModel.FeaturesStartDataVector,它调用了 StartVector,而 StartVector 又调用了 Prep。因此,由于已经调用 Prep 来检查整个数组的边界,因此无需调用它来检查写入数组的每个单独的 float32 边界。

关于go - 使用 FlatBuffers 更快地发送/写入 Float32 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58641296/

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