]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: parallelize loadDefines calls
authorMichael Podtserkovskii <michaelpo@meta.com>
Thu, 18 Apr 2024 11:28:13 +0000 (12:28 +0100)
committerGopher Robot <gobot@golang.org>
Tue, 3 Sep 2024 15:39:35 +0000 (15:39 +0000)
```
export CC="zig cc -target x86_64-linux"
hyperfine '../pkg/tool/darwin_arm64/cgo -objdir /tmp net/cgo_linux.go net/cgo_resnew.go net/cgo_socknew.go net/cgo_unix_cgo.go net/cgo_unix_cgo_res.go'
```

**Before**
```
  Time (mean ± sig):      1.293 s ±  0.017 s    [User: 0.472 s, System: 0.451 s]
  Range (min ... max):    1.263 s ...  1.316 s    10 runs

```

**After**
```
  Time (mean ±sig):     986.5 ms ±  22.6 ms    [User: 487.0 ms, System: 519.5 ms]
  Range (min ... max):   950.7 ms ... 1022.2 ms    10 runs

```

The version after changes is 25% faster for 5 input files (std "net" package).
I also tried to make CC artifictially slower (wrapper with sleep 0.2) and it showes same 25% performance increase.

Change-Id: I7a26fdc8d8a23b0df9bc71d30b96e82e2ddb943b
Reviewed-on: https://go-review.googlesource.com/c/go/+/581336
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/cgo/gcc.go
src/cmd/cgo/main.go

index 0f90761e14bf8ce5a5bbb4d760282eb59139d87a..cdda88fc8e8e5baf04d08a5fc88cf73a88e4b132 100644 (file)
@@ -193,7 +193,6 @@ func (p *Package) Translate(f *File) {
        var conv typeConv
        conv.Init(p.PtrSize, p.IntSize)
 
-       p.loadDefines(f)
        p.typedefs = map[string]bool{}
        p.typedefList = nil
        numTypedefs := -1
@@ -233,12 +232,14 @@ func (p *Package) Translate(f *File) {
 
 // loadDefines coerces gcc into spitting out the #defines in use
 // in the file f and saves relevant renamings in f.Name[name].Define.
-func (p *Package) loadDefines(f *File) {
+// Returns true if env:CC is Clang
+func (f *File) loadDefines(gccOptions []string) bool {
        var b bytes.Buffer
        b.WriteString(builtinProlog)
        b.WriteString(f.Preamble)
-       stdout := p.gccDefines(b.Bytes())
+       stdout := gccDefines(b.Bytes(), gccOptions)
 
+       var gccIsClang bool
        for _, line := range strings.Split(stdout, "\n") {
                if len(line) < 9 || line[0:7] != "#define" {
                        continue
@@ -261,7 +262,7 @@ func (p *Package) loadDefines(f *File) {
                }
 
                if key == "__clang__" {
-                       p.GccIsClang = true
+                       gccIsClang = true
                }
 
                if n := f.Name[key]; n != nil {
@@ -271,6 +272,7 @@ func (p *Package) loadDefines(f *File) {
                        n.Define = val
                }
        }
+       return gccIsClang
 }
 
 // guessKinds tricks gcc into revealing the kind of each
@@ -1722,7 +1724,7 @@ func checkGCCBaseCmd() ([]string, error) {
 }
 
 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
-func (p *Package) gccMachine() []string {
+func gccMachine() []string {
        switch goarch {
        case "amd64":
                if goos == "darwin" {
@@ -1795,7 +1797,7 @@ func (p *Package) gccCmd() []string {
        }
 
        c = append(c, p.GccOptions...)
-       c = append(c, p.gccMachine()...)
+       c = append(c, gccMachine()...)
        if goos == "aix" {
                c = append(c, "-maix64")
                c = append(c, "-mcmodel=large")
@@ -2187,10 +2189,10 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
 // and returns the corresponding standard output, which is the
 // #defines that gcc encountered while processing the input
 // and its included files.
-func (p *Package) gccDefines(stdin []byte) string {
+func gccDefines(stdin []byte, gccOptions []string) string {
        base := append(gccBaseCmd, "-E", "-dM", "-xc")
-       base = append(base, p.gccMachine()...)
-       stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
+       base = append(base, gccMachine()...)
+       stdout, _ := runGcc(stdin, append(append(base, gccOptions...), "-"))
        return stdout
 }
 
index 519d76c644ca6ed7ea3fb8575997cf1bd6ee73e0..28a4631181a239d1abd5d427e0b28d03c87ba84e 100644 (file)
@@ -24,6 +24,7 @@ import (
        "runtime"
        "sort"
        "strings"
+       "sync"
 
        "cmd/internal/edit"
        "cmd/internal/notsha256"
@@ -390,6 +391,8 @@ func main() {
        // Use the beginning of the notsha256 of the input to disambiguate.
        h := notsha256.New()
        io.WriteString(h, *importPath)
+       var once sync.Once
+       var wg sync.WaitGroup
        fs := make([]*File, len(goFiles))
        for i, input := range goFiles {
                if *srcDir != "" {
@@ -411,23 +414,34 @@ func main() {
                        fatalf("%s", err)
                }
 
-               // Apply trimpath to the file path. The path won't be read from after this point.
-               input, _ = objabi.ApplyRewrites(input, *trimpath)
-               if strings.ContainsAny(input, "\r\n") {
-                       // ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
-                       // all emit line directives, which don't permit newlines in the file path.
-                       // Bail early if we see anything newline-like in the trimmed path.
-                       fatalf("input path contains newline character: %q", input)
-               }
-               goFiles[i] = input
+               wg.Add(1)
+               go func() {
+                       defer wg.Done()
+                       // Apply trimpath to the file path. The path won't be read from after this point.
+                       input, _ = objabi.ApplyRewrites(input, *trimpath)
+                       if strings.ContainsAny(input, "\r\n") {
+                               // ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
+                               // all emit line directives, which don't permit newlines in the file path.
+                               // Bail early if we see anything newline-like in the trimmed path.
+                               fatalf("input path contains newline character: %q", input)
+                       }
+                       goFiles[i] = input
 
-               f := new(File)
-               f.Edit = edit.NewBuffer(b)
-               f.ParseGo(input, b)
-               f.ProcessCgoDirectives()
-               fs[i] = f
+                       f := new(File)
+                       f.Edit = edit.NewBuffer(b)
+                       f.ParseGo(input, b)
+                       f.ProcessCgoDirectives()
+                       gccIsClang := f.loadDefines(p.GccOptions)
+                       once.Do(func() {
+                               p.GccIsClang = gccIsClang
+                       })
+
+                       fs[i] = f
+               }()
        }
 
+       wg.Wait()
+
        cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
 
        if *objDir == "" {