首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将下面的线程模型从C++转换到go?

如何将下面的线程模型从C++转换到go?
EN

Stack Overflow用户
提问于 2011-10-22 10:55:44
回答 2查看 228关注 0票数 2

在我的C++项目中,我在磁盘上有一个大的GB二进制文件,我将该文件读入内存进行只读计算。

,我目前的C++实现包括将整个块读入内存一次,然后生成线程从块读取,以便进行各种计算(没有互斥量,并且运行很快)。从技术上讲,每个线程一次只需要文件的一小部分,所以在将来,我可能会将这个实现更改为使用mmap(),特别是当文件变得太大时。我已经注意到了这个gommap库,所以我认为我应该继续前进。

我应该采取什么方法来将我当前的C++线程模型(一大块只读内存)转换成一个go线程模型,同时考虑到运行时的效率?

戈鲁蒂人?其他选择?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-22 11:16:44

我相信这个答案会引起很大的反响,但我要说:

切换到Go不会减少运行时间,特别是在代码已经没有互斥的情况下。Go并不能保证高效率的平衡,而且目前也无法充分利用可用的内核。生成的代码比C++慢。Go目前的优势在于抽象清晰、并发性、而不是并行性。

预先读取整个文件并不是特别有效,如果你不得不通过内存进行回溯。直到很长一段时间后才会从缓存中删除文件的一部分,然后再重新加载。如果您的平台允许的话,您应该考虑内存映射,以便按需要从磁盘加载页面。

如果有任何激烈的程序间通信,或数据之间的依赖,您应该尝试使算法单线程。如果不了解应用于数据的例程,就很难说出来了,但听起来确实有可能过早地拔出线程,希望得到神奇的性能提升。

如果由于文件大小或其他平台约束而无法依赖内存映射,则应考虑使用扩展调用,从而重用单个文件描述符,并且只根据需要读取。

与往常一样,以下规则适用于优化。您必须配置文件。您必须检查您从工作解决方案中所做的更改是否正在改进。通常,您会发现内存映射、线程和其他诡计对性能没有明显的影响。这也是一场艰难的战斗,如果你是从C或C++切换。

此外,您应该生成goroutines来处理文件的每个部分,并通过一个通道减少计算结果。确保将GOMAXPROCS设置为适当的值。

票数 3
EN

Stack Overflow用户

发布于 2011-10-22 19:17:49

这个程序将文件中的所有字节加在多个goroutines中(而不必担心溢出)。

您需要为您的情况重新实现processChunk和aggregateResults。您还可能希望更改结果通道的通道类型。根据您正在做的事情,您甚至可能不需要聚合结果。块大小和通道的缓冲区大小是您可以调整的其他旋钮。

代码语言:javascript
复制
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)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7858988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档