This is an archive of the discontinued LLVM Phabricator instance.

[mlir][StorageUniquer] Refactor parametric storage to use sharded dense sets
ClosedPublic

Authored by rriddle on Oct 18 2020, 3:09 PM.

Details

Summary

This revisions implements sharding in the storage of parametric instances to decrease lock contention by sharding out the allocator/mutex/etc. to use for a specific storage instance based on the hash key. This is a somewhat common approach to reducing lock contention on data structures, and is used by the concurrent hashmaps provided by folly/java/etc. For several compilations tested, this removed all/most lock contention from profiles and reduced compile time by several seconds.

Diff Detail

Event Timeline

rriddle created this revision.Oct 18 2020, 3:09 PM
rriddle requested review of this revision.Oct 18 2020, 3:09 PM

Right now I've set it so that all types of storage instances use 8 shards, but that isn't that great. Some storage instances have higher concurrency needs, e.g. DictionaryAttr, while others have close to none, e.g. IntegerType. It might be a good idea to expose the level of concurrency expected by specific storage instances, but left that out from the initial patch. Thoughts on this?

ftynse added a subscriber: ftynse.Oct 19 2020, 12:51 AM
ftynse added inline comments.
mlir/lib/Support/StorageUniquer.cpp
158

This requires numShards to be a power of 2, worth documenting somewhere + adding an assert. Alternatively, round to the closest power of two before this.

jpienaar added inline comments.Oct 19 2020, 2:44 PM
mlir/lib/Support/StorageUniquer.cpp
91

Do we need to guard these on when threading is enabled? E.g., have the non threaded case be completely non-sharded and so not even create an array?

132

I don't follow this, why do we not care about which shard for arbitrary mutation?

Also does this need to be public?

rriddle updated this revision to Diff 299785.Oct 21 2020, 12:51 PM
rriddle marked 3 inline comments as done.

Resolve comments

mlir/lib/Support/StorageUniquer.cpp
91

Updated to wrap all of the complicated bits within an if LLVM_ENABLE_THREADS so that we don't incur any complexity when threading is disabled at build time.

132

I don't follow this, why do we not care about which shard for arbitrary mutation?

Updated to find the shard that allocated the storage instance.

Also does this need to be public?

Yes, but it is fine because everything here is local to the StorageUniquer.cpp file. We could make it private, but only by moving it to be nested within the StorageUniquerImpl class.

158

Added an assert for now given that this is still local to this file. If we expose concurrency to users, I suspect we wouldn't expose exact shard numbers but have something akin to concurrency levels.

Thanks for the review!

jpienaar accepted this revision.Oct 26 2020, 5:45 PM

Thanks!

This revision is now accepted and ready to land.Oct 26 2020, 5:45 PM