通道元素类型太大 Golang

ben*_*ano 5 arrays channel matrix go goroutine

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

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

const n = 10
Run Code Online (Sandbox Code Playgroud)

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

a := make(chan [n][n]int)
Run Code Online (Sandbox Code Playgroud)

这适用于任何低于大约值的任何东西12n但任何更大的东西都会出现以下错误:

channel element type too large (>64kB)
Run Code Online (Sandbox Code Playgroud)

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

a := make(chan [n][n]int, 1000)
Run Code Online (Sandbox Code Playgroud)

我是正确使用缓冲通道还是它们不是解决此问题的方法?任何关于我如何推进这一点的提示都非常感谢。

编辑:继给出的答案和评论之后,我现在正在尝试创建一个全局矩阵,该矩阵是空白的并且 go 例程可以写入。

const n int = 1024

blank [n][n]int
Run Code Online (Sandbox Code Playgroud)

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

icz*_*cza 5

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

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

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

a := make(chan *[n][n]int)
Run Code Online (Sandbox Code Playgroud)

然后当然你必须在通道上发送指针,你将从它接收指针,例如:

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
Run Code Online (Sandbox Code Playgroud)

Go Playground上试一试。

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

var v [n][n]int
// Making a copy:
v2 := v
a <- &v2 // Sending address of the copy
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

var result [n][n]int
Run Code Online (Sandbox Code Playgroud)

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