简单并发例子,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分配内存太慢了还是怎么回事

 

 

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