duanquan4451 2017-05-24 12:04
浏览 33
已采纳

频道元素类型过大

I'm writing a program that works with matrixes in parallel.

My matrixes are created using a constant n.

const n = 10

The channels are created with the following code:

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

This works fine for anything under a value of around 12 for n however anything greater and the following error is given:

channel element type too large (>64kB)

Looking at tutorials etc, and it seem buffered channels may be the way to solve this but I tried doing this with the following code and the same error was given:

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

Am I using buffered channels correctly or are they not the way to solve this issue? Any tips on how I can move forward with this greatly appreciated.

EDIT: Following on from the answer given and comments I'm now trying to create a global matrix which is blank and go routines can write to.

const n int = 1024

blank [n][n]int

I'm unsure how it could be declared globally and have attempted the above to solve this. Does it need initialising globally? Everything I seem to try gives errors.

  • 写回答

1条回答 默认 最新

  • douhu2890 2017-05-24 12:13
    关注

    The channel being buffered or not has nothing to do with this, the error is not with the space for storing elements but with the size of a single element. The size limit of the channel's element type is an implementation detail / restriction, you can't do anything about that.

    And if you try to use an element type violating this, that signals you're doing something wrong (something you shouldn't do). Whenever you send a value on a channel, the value will be copied. So sending >64KB values on a channel is not really efficient.

    Instead choose an element type which is small. The choice requiring the least change would be to use a pointer to your type: *[n][n]int.

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

    Then of course you have to send pointers on the channel, and you'll receive pointers from it, e.g.:

    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
    

    Try it on the Go Playground.

    You should also keep in mind that since now we're sending / receiving pointers on the channel, it will point to the same array value, and thus modifying the pointed value will modify the same array whose address we sent on the channel. If this is unwanted, make a copy before sending, and send the address of the copy:

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

    You should also consider working with slices instead of arrays.

    Edit:

    Declaring a global array is as easy as this:

    var result [n][n]int
    

    (It must be outside of other blocks, in the file scope.)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题