通道元素类型太大 Golang
Channel Element type too large Golang
我正在编写一个并行处理矩阵的程序。
我的矩阵是使用常数 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)
我使用缓冲通道是否正确,或者它们不是解决此问题的方法?非常感谢有关我如何继续前进的任何提示。
编辑:根据给出的答案和评论,我现在正在尝试创建一个空白的全局矩阵,go routines 可以写入。
const n int = 1024
blank [n][n]int
我不确定如何在全球范围内声明它,并已尝试通过上述方法解决此问题。是否需要全局初始化?我似乎尝试的一切都会出错。
通道是否缓冲与此无关,错误不是存储元素的space而是单个元素的大小。频道元素类型的大小限制是一个实现细节/限制,您对此无能为力。
如果您尝试使用违反此规定的元素类型,则表明您做错了什么(您不应该做的事情)。每当您在通道上发送一个值时,该值将被复制。所以在通道上发送 >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 instead of arrays。
编辑:
声明一个全局数组就这么简单:
var result [n][n]int
(必须在其他块之外,在文件范围内。)
我正在编写一个并行处理矩阵的程序。
我的矩阵是使用常数 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)
我使用缓冲通道是否正确,或者它们不是解决此问题的方法?非常感谢有关我如何继续前进的任何提示。
编辑:根据给出的答案和评论,我现在正在尝试创建一个空白的全局矩阵,go routines 可以写入。
const n int = 1024
blank [n][n]int
我不确定如何在全球范围内声明它,并已尝试通过上述方法解决此问题。是否需要全局初始化?我似乎尝试的一切都会出错。
通道是否缓冲与此无关,错误不是存储元素的space而是单个元素的大小。频道元素类型的大小限制是一个实现细节/限制,您对此无能为力。
如果您尝试使用违反此规定的元素类型,则表明您做错了什么(您不应该做的事情)。每当您在通道上发送一个值时,该值将被复制。所以在通道上发送 >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 instead of arrays。
编辑:
声明一个全局数组就这么简单:
var result [n][n]int
(必须在其他块之外,在文件范围内。)