mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: parallelize loadDefines calls
``` 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>
This commit is contained in:
parent
3d4daa38a7
commit
d555358bf8
2 changed files with 39 additions and 23 deletions
|
|
@ -193,7 +193,6 @@ func (p *Package) Translate(f *File) {
|
||||||
var conv typeConv
|
var conv typeConv
|
||||||
conv.Init(p.PtrSize, p.IntSize)
|
conv.Init(p.PtrSize, p.IntSize)
|
||||||
|
|
||||||
p.loadDefines(f)
|
|
||||||
p.typedefs = map[string]bool{}
|
p.typedefs = map[string]bool{}
|
||||||
p.typedefList = nil
|
p.typedefList = nil
|
||||||
numTypedefs := -1
|
numTypedefs := -1
|
||||||
|
|
@ -233,12 +232,14 @@ func (p *Package) Translate(f *File) {
|
||||||
|
|
||||||
// loadDefines coerces gcc into spitting out the #defines in use
|
// loadDefines coerces gcc into spitting out the #defines in use
|
||||||
// in the file f and saves relevant renamings in f.Name[name].Define.
|
// 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
|
var b bytes.Buffer
|
||||||
b.WriteString(builtinProlog)
|
b.WriteString(builtinProlog)
|
||||||
b.WriteString(f.Preamble)
|
b.WriteString(f.Preamble)
|
||||||
stdout := p.gccDefines(b.Bytes())
|
stdout := gccDefines(b.Bytes(), gccOptions)
|
||||||
|
|
||||||
|
var gccIsClang bool
|
||||||
for _, line := range strings.Split(stdout, "\n") {
|
for _, line := range strings.Split(stdout, "\n") {
|
||||||
if len(line) < 9 || line[0:7] != "#define" {
|
if len(line) < 9 || line[0:7] != "#define" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -261,7 +262,7 @@ func (p *Package) loadDefines(f *File) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "__clang__" {
|
if key == "__clang__" {
|
||||||
p.GccIsClang = true
|
gccIsClang = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if n := f.Name[key]; n != nil {
|
if n := f.Name[key]; n != nil {
|
||||||
|
|
@ -271,6 +272,7 @@ func (p *Package) loadDefines(f *File) {
|
||||||
n.Define = val
|
n.Define = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return gccIsClang
|
||||||
}
|
}
|
||||||
|
|
||||||
// guessKinds tricks gcc into revealing the kind of each
|
// 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".
|
// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
|
||||||
func (p *Package) gccMachine() []string {
|
func gccMachine() []string {
|
||||||
switch goarch {
|
switch goarch {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
if goos == "darwin" {
|
if goos == "darwin" {
|
||||||
|
|
@ -1795,7 +1797,7 @@ func (p *Package) gccCmd() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
c = append(c, p.GccOptions...)
|
c = append(c, p.GccOptions...)
|
||||||
c = append(c, p.gccMachine()...)
|
c = append(c, gccMachine()...)
|
||||||
if goos == "aix" {
|
if goos == "aix" {
|
||||||
c = append(c, "-maix64")
|
c = append(c, "-maix64")
|
||||||
c = append(c, "-mcmodel=large")
|
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
|
// and returns the corresponding standard output, which is the
|
||||||
// #defines that gcc encountered while processing the input
|
// #defines that gcc encountered while processing the input
|
||||||
// and its included files.
|
// 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(gccBaseCmd, "-E", "-dM", "-xc")
|
||||||
base = append(base, p.gccMachine()...)
|
base = append(base, gccMachine()...)
|
||||||
stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
|
stdout, _ := runGcc(stdin, append(append(base, gccOptions...), "-"))
|
||||||
return stdout
|
return stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"cmd/internal/edit"
|
"cmd/internal/edit"
|
||||||
"cmd/internal/notsha256"
|
"cmd/internal/notsha256"
|
||||||
|
|
@ -390,6 +391,8 @@ func main() {
|
||||||
// Use the beginning of the notsha256 of the input to disambiguate.
|
// Use the beginning of the notsha256 of the input to disambiguate.
|
||||||
h := notsha256.New()
|
h := notsha256.New()
|
||||||
io.WriteString(h, *importPath)
|
io.WriteString(h, *importPath)
|
||||||
|
var once sync.Once
|
||||||
|
var wg sync.WaitGroup
|
||||||
fs := make([]*File, len(goFiles))
|
fs := make([]*File, len(goFiles))
|
||||||
for i, input := range goFiles {
|
for i, input := range goFiles {
|
||||||
if *srcDir != "" {
|
if *srcDir != "" {
|
||||||
|
|
@ -411,23 +414,34 @@ func main() {
|
||||||
fatalf("%s", err)
|
fatalf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply trimpath to the file path. The path won't be read from after this point.
|
wg.Add(1)
|
||||||
input, _ = objabi.ApplyRewrites(input, *trimpath)
|
go func() {
|
||||||
if strings.ContainsAny(input, "\r\n") {
|
defer wg.Done()
|
||||||
// ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
|
// Apply trimpath to the file path. The path won't be read from after this point.
|
||||||
// all emit line directives, which don't permit newlines in the file path.
|
input, _ = objabi.ApplyRewrites(input, *trimpath)
|
||||||
// Bail early if we see anything newline-like in the trimmed path.
|
if strings.ContainsAny(input, "\r\n") {
|
||||||
fatalf("input path contains newline character: %q", input)
|
// ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
|
||||||
}
|
// all emit line directives, which don't permit newlines in the file path.
|
||||||
goFiles[i] = input
|
// 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 := new(File)
|
||||||
f.Edit = edit.NewBuffer(b)
|
f.Edit = edit.NewBuffer(b)
|
||||||
f.ParseGo(input, b)
|
f.ParseGo(input, b)
|
||||||
f.ProcessCgoDirectives()
|
f.ProcessCgoDirectives()
|
||||||
fs[i] = f
|
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])
|
cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
|
||||||
|
|
||||||
if *objDir == "" {
|
if *objDir == "" {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue