Skip to content

Use direct pointers as Type IDs - #2745

Merged
tlively merged 4 commits into
WebAssembly:masterfrom
tlively:type-pointers
Apr 13, 2020
Merged

tlively merged 4 commits into
WebAssembly:masterfrom
tlively:type-pointers

Conversation

@tlively

@tlively tlively commented Apr 10, 2020

Copy link
Copy Markdown
Member

Instead of using indices into the global interned type table. This
means that a lock is never needed to access an expanded Type. The
Type lock is now only acquired when a complex Type is created. On a
real-world wasm2js workload this improves wall clock time by 23% on my
machine with 72 cores and makes traffic on the Type lock entirely
insignificant.

Before

72 cores
real 6.914s
user 184.014s
sys 3.995s

1 core
real 25.903s
user 25.658s
sys 0.253s

After

72 cores
real 5.349s
user 70.309s
sys 9.691s

1 core
real 25.859s
user 25.615s
sys 0.253s

@tlively
tlively requested a review from kripken April 10, 2020 04:34
Instead of using indices into the global interned type table. This
means that a lock is *never* needed to access an expanded Type. The
Type lock is now only acquired when a complex Type is created. On a
real-world wasm2js workload this improves wall clock time by 23% on my
machine with 72 cores and makes traffic on the Type lock entirely
insignificant.

**Before**

72 cores
real    0m6.914s
user    184.014s
sys     0m3.995s

1 core
real    0m25.903s
user    0m25.658s
sys     0m0.253s

**After**

72 cores
real    5.349s
user    70.309s
sys     9.691s

1 core
real    25.859s
user    25.615s
sys     0.253s
@tlively

tlively commented Apr 10, 2020

Copy link
Copy Markdown
Member Author

Ah, the tracing in the C API needs to be redone because tuple Type IDs (aka the locations in memory of their canonical Type vectors) are not stable between the traced program and the program emitted as the trace.

@kripken kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea!

Comment thread src/passes/LocalCSE.cpp Resolved
Comment thread src/wasm/wasm-type.cpp Outdated
}
id = typeLists.size();
typeLists.push_back(std::make_unique<std::vector<Type>>(types));
auto* vec = new std::vector<Type>(types);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this deleted?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NEVER! The canonical type vectors live for the length of the process, just like they did before.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds ok, but before it was making a unique ptr, so it was cleaned up, wasn't it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the unique_ptr was cleaned up, but only when global destructors run at the end of the program. I could make this a unique_ptr again but I'm not sure whether that has any value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would avoid false positives with leak detection tools. I'm unsure myself if that is worth the cost.

@tlively

tlively commented Apr 13, 2020

Copy link
Copy Markdown
Member Author

@kripken The latest commit adds unique_ptrs to avoid false leaks and switches to using a normal mutex for simplicity. I think this should be good to go now.

Comment thread src/wasm/wasm-type.cpp Outdated
// Track unique_ptrs for constructed types to avoid leaks
std::vector<std::unique_ptr<std::vector<Type>>> constructedTypes;

// Maps from type vectors to the canonical Type IS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is IS here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, should be ID.

Comment thread src/wasm/wasm-type.cpp
if (types.size() == 1) {
*this = types[0];
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I don't understand how this all works yet (maybe some overview in types.h?). Here in init we take a lock on anything that doesn't have 0 or 1 elements. Are we somehow not calling init as much? If so I missed that part (or something else).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem was never that we called init a lot, it was that we called expand a lot and it acquired the lock. Now expand never acquires the lock. I'll add documentation about how the IDs work in the header.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, thanks. Now I get it!

@tlively
tlively merged commit c16bfee into WebAssembly:master Apr 13, 2020
@kripken

kripken commented Apr 13, 2020

Copy link
Copy Markdown
Member

This seems to have hit an error on the mac CI after landing: https://travis-ci.org/github/WebAssembly/binaryen/jobs/674594365

@tlively
tlively deleted the type-pointers branch April 24, 2020 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants