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

简单并发例子,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 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀