8000 perf: explore pushing parts of MVCC or KV evaluation into C++ · Issue #17172 · cockroachdb/cockroach · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

perf: explore pushing parts of MVCC or KV evaluation into C++ #17172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
petermattis opened this issue Jul 23, 2017 · 7 comments
Closed

perf: explore pushing parts of MVCC or KV evaluation into C++ #17172

petermattis opened this issue Jul 23, 2017 · 7 comments
Assignees
Labels
C-performance Perf of queries or internals. Solution not expected to change functional behavior.
Milestone

Comments

@petermattis
Copy link
Collaborator

We've observed in the past that minimizing Go/C++ crossings in storage/engine/mvcc.go is a useful performance optimization. But many of the interesting methods in mvcc.go still perform multiple Cgo calls. And stepping up a level, evaluation of a KV operation can often perform multiple MVCC operations.

The challenge in pushing more logic into C++ is in the Go/C++ boundary. Currently, Go code manually fills in C (not C++) structures and passes those C structures to C routines. When data is returned from C++ the Go code manually copies it from the C structs. So far, we've avoided passing any complicated structure and thus the C++ interface is very basic, knowing only about strings and timestamps.

Cgo does not provide a facility for passing Go structures to C. I think we can provide that facility ourselves. Specifically, we can use reflect to auto-generate C++ code that can access a Go data structure. Using reflect we can find the types and byte offsets of any field for a given Go type. Auto-generating C++ code from these byte offsets is then relatively straightforward.

Note that passing an arbitrary Go structure to C++ would violate the rules in https://golang.org/cmd/cgo/#hdr-Passing_pointers. Those rules are somewhat stricter than necessary and we'd definitely be playing on the edge here. The auto-generated code could only be used for reading the Go structure, not for writing as we'd definitely not want to deal with supporting the GC write barrier. This implies that returning a structure from C++ to Go would be more limited. A final limitation is that this approach would not allow C++ to iterate over a Go map, but so far none of the protos in roachpb use Go maps.

The proposed steps of exploration are:

  1. Write a tool to auto-generate C++ for accessing a Go data structure.
  2. Convert one of the MVCC routines (e.g. MVCCGet) to C++ and benchmark the performance improvement.
  3. Evaluate where it makes sense to push Go code into C++ (the decision might be no change from the status quo).
@petermattis petermattis added this to the Later milestone Jul 23, 2017
@petermattis petermattis self-assigned this Jul 23, 2017
@bdarnell
Copy link
Contributor

Go has two ways to interface with foreign code: cgo and assembly. The assembly interface doesn't interact with the scheduler, so it's much faster (but it has limitations such as not being suitable for code that may make system calls). There are tricks like https://github.com/minio/c2goasm for calling C code via the assembly interface; we may be able to do something like this to reduce the cost of crossing the boundary for frequently-called functions.

@petermattis
Copy link
Collaborator Author

c2goasm has a number of limitations right now (e.g. arguments need to be 64-bits in size), and I'm not seeing how to use it to make a C/C++ function call, but its good to keep the use of assembly as a trampoline into C/C++ as an option.

@petermattis
Copy link
Collaborator Author

I prototyped a tool which uses reflection to generate C++ to read a Go struct. It can't handle maps, channels or interfaces, but everything else is fairly straightforward. Another possibility for using this tool would be to move either the timestamp cache or raft entry cache into C++. Both data structures have interfaces that would be awkward to shoehorn into the cgo interface without overhead.

@petermattis
Copy link
Collaborator Author

Also, see golang/go#16051 for how the Go race detector calls into C++ without the cgo overhead. This is low-level and architecture specific, but might be worthwhile.

@knz
Copy link
Contributor
knz commented Aug 7, 2017

just curious, how much confident are you that the GC doesn't rewrite pointers / move data structures concurrently? (e.g. to reduce fragmentation)

@petermattis
Copy link
Collaborator Author

just curious, how much confident are you that the GC doesn't rewrite pointers / move data structures concurrently? (e.g. to reduce fragmentation)

I'm 100% confident that it doesn't. The concern is whether a future version of the GC will do so. The current cgo pointer passing rules can be seen as leaving open this possibility, though I'm not aware of any work that is pushing towards it.

petermattis added a commit to petermattis/cockroach that referenced this issue Aug 9, 2017
Generate C++ code for read-only access of a Go structure.

See cockroachdb#17172
petermattis added a commit to petermattis/cockroach that referenced this issue Aug 11, 2017
Generate C++ code for read-only access of a Go structure.

See cockroachdb#17172
@petermattis petermattis added the C-performance Perf of queries or internals. Solution not expected to change functional behavior. label Sep 27, 2017
@petermattis petermattis modified the milestones: 2.0, 2.1 Jan 25, 2018
@petermattis
Copy link
Collaborator Author

With the introduction of the arena skiplist timestamp-cache and reimplementing MVCC{Scan,Get} in C++, I'm not aware of any other work to do in this area at this time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-performance Perf of queries or internals. Solution not expected to change functional behavior.
Projects
None yet
Development

No branches or pull requests

3 participants
0