【问题标题】:Channel Element type too large Golang通道元素类型太大 Golang
【发布时间】:2017-10-24 18:30:46
【问题描述】:

我正在编写一个并行处理矩阵的程序。

我的矩阵是使用常量n 创建的。

const n = 10

频道是使用以下代码创建的:

a := make(chan [n][n]int)

对于n 的值低于12 的任何值都可以正常工作,但是任何更大的值都会出现以下错误:

channel element type too large (>64kB)

查看教程等,似乎缓冲通道可能是解决此问题的方法,但我尝试使用以下代码执行此操作并给出相同的错误:

a := make(chan [n][n]int, 1000)

我是否正确使用了缓冲通道,或者它们不是解决此问题的方法?非常感谢任何有关我如何继续前进的提示。

编辑:根据给出的答案和 cmets,我现在正在尝试创建一个空白的全局矩阵,并且 go 例程可以写入。

const n int = 1024

blank [n][n]int

我不确定如何在全局范围内声明它,并尝试通过上述方法解决这个问题。它需要全局初始化吗?我似乎尝试的一切都会出错。

【问题讨论】:

    标签: arrays matrix go channel goroutine


    【解决方案1】:

    通道是否被缓冲与此无关,错误不在于存储元素的空间,而在于单个元素的大小。通道元素类型的大小限制是一个实现细节/限制,您对此无能为力。

    如果您尝试使用违反此规则的元素类型,则表明您做错了(您不应该做的事情)。每当您在通道上发送值时,都会复制该值。所以在一个通道上发送大于 64KB 的值并不是很有效。

    请选择较小的元素类型。需要最少更改的选择是使用指向您的类型的指针:*[n][n]int

    a := make(chan *[n][n]int)
    

    那你当然要在通道上发送指针,然后你会从它接收指针,例如:

    const n = 132
    a := make(chan *[n][n]int)
    
    go func() {
        var v [n][n]int
        a <- &v // Sending a pointer
    }()
    
    v2 := <-a
    fmt.Println(v2)  // It's a pointer
    fmt.Println(*v2) // It's an array value
    

    Go Playground 上试用。

    您还应该记住,由于现在我们在通道上发送/接收指针,它将指向相同的数组值,因此修改指向的值将修改我们在通道上发送其地址的同一数组.如果不需要,请在发送前制作一份副本,并发送副本的地址:

    var v [n][n]int
    // Making a copy:
    v2 := v
    a <- &v2 // Sending address of the copy
    

    您还应该考虑使用slices 而不是arrays

    编辑:

    声明一个全局数组就这么简单:

    var result [n][n]int
    

    (它必须在文件范围内的其他块之外。)

    【讨论】:

    • 您好,感谢您的回答,我创建一个名为 matrix 的结构并使用它而不是每次都使用 [n][n]int 是否有意义?
    • @benjano 这不会改变任何东西,结构类型的大小不能小于其所有字段类型大小的总和。
    • 如果我想对矩阵进行并行计算,是否需要一个全局变量,其中包含一个相同大小的空白矩阵,然后可以保存到?
    • @benjano 这取决于您计算的性质。如果计算读/写相同的元素,则必须同步访问。如果计算只读取元素,则不需要同步,甚至不需要通道。
    • 我正在生成两个随机矩阵,然后将它们加在一起。目前我的程序将矩阵分成两半并将两半传递到两个单独的 goroutines 中,然后同时处理它们。然后将这两部分传递出去并重建。然而,由于最后需要重建,它比顺序版本慢得多。我希望能够写入并保存到另一个矩阵,这将给出结果。
    猜你喜欢
    • 2011-09-14
    • 1970-01-01
    • 2020-02-07
    • 2022-12-07
    • 1970-01-01
    • 2012-04-25
    • 2017-10-27
    • 2017-05-16
    • 2016-05-19
    相关资源
    最近更新 更多