Aiky哇 2021-04-12 20:40 采纳率: 50%
浏览 41
已结题

简单并发例子,go没法跑满cpu

package main
import(
"sync"
)

func ff(str string) int {
    var result string
    result = str+" "
    lenn:=len(result)
    return lenn
}

func ff2(str string) int {
    var result string
    result = str
    lenn:=len(result)
    return lenn
}

func main(){
        s := "asdbvbhfbdjaasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklbag"

        n:=1000
        var wg sync.WaitGroup
        wg.Add(n)
        for i:=1;i<=n;i++{
                go func() int{
                        num:=0
                        for{
                                //num+=ff(s)
                                num=ff2(s)

                        }
                        wg.Done()
                        return num
                }()
        }
        wg.Wait()
}

写了简单的并发例子,调用ff时,cpu的使用情况如下,并没有使用满:

但是调用ff2时,cpu的使用情况如下,使用满了:

想知道为什么go在调用ff时没有办法将cpu使用满

另外加减并发数并不会对cpu使用率有什么影响

当前总内存剩余非常充足

尝试使用sync.Pool进行分配也是这个结果

go版本为1.13,机器内核数为16

希望大佬能帮我解释一下,,是go分配内存太慢了还是怎么回事

 

 

  • 写回答

1条回答 默认 最新

  • Junebao 2022-09-10 18:28
    关注

    img


    没错,大量的 CPU 消耗在拼接字符串的分配内存上,想要跑满思路就是优化掉内存分配过程,用 pool 是可以做到的,提前分配一个足够的字节数组,然后通过零拷贝的方式把字符串和字节数组做转换:

    package main
    
    // package main
    import (
        "net/http"
        _ "net/http/pprof"
        "reflect"
        "sync"
        "unsafe"
    )
    
    var pool sync.Pool
    
    func bytes2Str(slice []byte) string {
        return *(*string)(unsafe.Pointer(&slice))
    }
    
    func str2Bytes(s string) []byte {
        sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
        bh := reflect.SliceHeader{
            Data: sh.Data,
            Len:  sh.Len,
            Cap:  sh.Len,
        }
        return *(*[]byte)(unsafe.Pointer(&bh))
    }
    
    
    func ff(str string) int {
        bs := str2Bytes(str)
        res := pool.Get().([]byte)
        size1 := len(bs)
        copy(res[:size1], bs)
        res[size1] = ' '
        result := bytes2Str(res[:size1 + 1])
        lenn := len(result)
        pool.Put(res)
        return lenn
    }
    
    func ff2(str string) int {
        var result string
        result = str
        lenn := len(result)
        return lenn
    }
    
    func main() {
        go func() {
            http.ListenAndServe("localhost:6060", nil)
        }()
        pool = sync.Pool{
            New: func() any {
                return make([]byte, 1300)
            },
        }
        s := "asdbvbhfbdjaasdbvbhfbjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklasdbvbhfbdjaibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklibfdjiagjnagjnagjandgjangkjxnzjlbgjbgjfdjkgbjkalbgjkldbajgklbag"
    
        n := 10000
        var wg sync.WaitGroup
        wg.Add(n)
        for i := 1; i <= n; i++ {
            go func() int {
                num := 0
                for {
                    num = ff(s)
                    // num=ff2(s)
    
                }
                wg.Done()
                return num
            }()
        }
        wg.Wait()
    }
    

    img

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

报告相同问题?

问题事件

  • 系统已结题 9月18日
  • 已采纳回答 9月10日

悬赏问题

  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测