如何将下面的线程模型从c++转换为go
How do I translate the following threading model from C++ to go?
在我的c++项目中,我在磁盘上有一个大的GB二进制文件,我将它读入内存用于只读计算。
我目前的c++实现包括将整个块读入内存一次,然后生成线程从块中读取,以便进行各种计算(无互斥,运行迅速)。从技术上讲,每个线程一次实际上只需要文件的一小部分,因此在将来,我可能会更改此实现以使用mmap(),特别是当文件变得太大时。我已经注意到这个gommap库,所以我认为我应该继续讨论。
我应该采取什么方法将我当前的c++线程模型(一大块只读内存)转换为go线程模型,同时保持运行时效率?
了goroutine吗?选择呢?
我相信这个答案会引起很多争议,但是下面是:
切换到Go不会减少运行时间,特别是如果你的代码已经没有互斥锁。Go不能保证有效地平衡程序,目前也不能充分利用可用的内核。生成的代码比c++慢。Go当前的优势在于清晰的抽象和并发性,而不是并行性。
如果你必须在内存中回溯,那么预先读取整个文件并不是特别有效。稍后才会再次使用的文件部分将从缓存中删除,稍后才会重新加载。如果您的平台允许的话,您应该考虑内存映射,以便在需要时从磁盘加载页面。
如果有任何密集的例程间通信,或数据之间的依赖关系,你应该尝试使算法单线程。如果不更多地了解应用于数据的例程,这很难说,但听起来确实有可能您过早地取出线程,希望获得神奇的性能提升。
如果由于文件大小或其他平台限制而无法依赖内存映射,则应该考虑使用pread调用,从而重用单个文件描述符,并且只在需要时读取。
与往常一样,以下规则适用于优化。必须配置文件。您必须检查您对工作解决方案所做的更改是否正在改进。通常情况下,您会发现内存映射、线程和其他技巧对性能没有明显的影响。如果你从C或c++切换过来,这也是一场艰苦的战斗。
此外,您应该生成处理文件的每个部分的例程,并通过通道减少计算结果。请确保将GOMAXPROCS
设置为合适的值。
此程序在多个例程中对文件中的所有字节求和(无需担心溢出)。
你需要重新实现processChunk和aggregateResults。您可能还想更改结果通道的通道类型。根据您正在做的事情,您甚至可能不需要汇总结果。块大小和通道的缓冲区大小是您可以调整的其他旋钮。
package main
import (
"fmt"
"io/ioutil"
)
func main() {
data, err := ioutil.ReadFile("filename")
if err != nil {
// handle this error somehow
panic(err.String())
}
// Adjust this to control the size of chunks.
// I've chosen it arbitrarily.
const chunkSize = 0x10000
// This channel's unbuffered. Add a buffer for better performance.
results := make(chan int64)
chunks := 0
for len(data) > 0 {
size := chunkSize
if len(data) < chunkSize {
size = len(data)
}
go processChunk(data[:size], results)
data = data[size:]
chunks++
}
aggregateResults(results, chunks)
}
func processChunk(chunk []byte, results chan int64) {
sum := int64(0)
for _, b := range chunk {
sum += int64(b)
}
results <- sum
}
func aggregateResults(results chan int64, chunks int) {
sum := int64(0)
for chunks > 0 {
sum += <-results
chunks--
}
fmt.Println("The sum of all bytes is", sum)
}
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++