-
Notifications
You must be signed in to change notification settings - Fork 624
RWSet performance fixes, LockFreeArray performance fixes and tests #1401
Conversation
return; | ||
} | ||
rw_set_.insert(rw_set_it, std::make_pair(location, RWType::READ)); | ||
rw_set_[location] = RWType::READ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we have still two lookups here, one in line 99 and one in line 103. Is it even possible to do this with a single lookup? No, because some other thread could have changed the RW set between these to lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As best as I can tell, based on our current semantics we can't get away from two lookups on Read, or Delete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I have some questions about the RW set, but maybe I just missed something again.
PELOTON_ASSERT(rw_set_.count(location) == 0 || | ||
(rw_set_[location] != RWType::DELETE && | ||
rw_set_[location] != RWType::INS_DEL)); | ||
rw_set_[location] = RWType::UPDATE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some functionality got lost here. If rw_type == RWType::INSERT
it should not be update to RWType::UPDATE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I'll rearrange that logic. I was trying to get away from two lookups in the case of an insert but it won't allow that.
return false; | ||
} | ||
if (rw_set_it != rw_set_.end() && rw_set_it->second == RWType::INSERT) { | ||
rw_set_it->second = RWType::INS_DEL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am just wondering - what does happen, if the value of rw_set_it->second
changes between line 130 and line 131/133. Do we still do the right thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it's a race that isn't handled in the current semantics of our RWSet. The hope is that we'll eventually get rid of the INS_DEL type anyway when we stop reusing tuple slots.
test/common/lock_free_array_test.cpp
Outdated
{ | ||
LockFreeArray<value_type> array; | ||
|
||
value_type invalid_value = 6288; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just any sentinel value for this test that wasn't inserted will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use INVALID_OID
instead.
@pervazea ran a microbenchmark of this branch against master that showed a drop in calls to StorageManager::GetTileGroup (and thereby CuckooMap::Find) from 1229 to 1083. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. I have two main concerns.
- I am not entirely sure if using
count
on theunordered_map
is a good idea. It seems semantically wrong. - I think you need to revert the change in return type of
RecordDelete
. I would definitely check with @apavlo or @yingjunwu about why we returned different values at different conditions. And why this didn't trigger a test failure. - The
is_written_
andinsert_count_
can be used to make our commits/aborts faster. Because with MVCC, you'd be running such a transaction under snapshot isolation by default. Please change that and talk to Andy about probably handling that condition.
Lastly, can you please add some numbers for this branch vs the master. (Probably run TPC-C & YCSB)? So at a later stage we'd have a point of reference for our performance.
@@ -655,12 +655,20 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( | |||
|
|||
// TODO (Pooja): This might be inefficient since we will have to get the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this TODO, your code has done what the TODO was about.
@@ -807,11 +815,20 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction( | |||
// Iterate through each item pointer in the read write set | |||
// TODO (Pooja): This might be inefficient since we will have to get the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, you can remove this TODO.
@@ -80,102 +78,63 @@ void TransactionContext::Init(const size_t thread_id, | |||
|
|||
isolation_level_ = isolation; | |||
|
|||
is_written_ = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little unsure about removing the is_written_
and insert_count_
. These variables can be used to make Commits and Aborts faster. If you figure out that the is_written_
is false, you can take an entirely different code path and treat it like a READ_ONLY
transaction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is okay if we get rid of insert_count_
but we should definitely use is_written_
. It will help with multi statement transactions that are not explicitly set to read only.
} | ||
|
||
void TransactionContext::RecordRead(const ItemPointer &location) { | ||
|
||
PELOTON_ASSERT(rw_set_.count(location) == 0 || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why count
? Shouldn't this be a find
? It makes sense to usecount
withunordered_multimap
, the unordered_map
can never contain more than one element with the same key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't really make a difference, but sure I'll change it.
} | ||
|
||
bool TransactionContext::RecordDelete(const ItemPointer &location) { | ||
void TransactionContext::RecordDelete(const ItemPointer &location) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.
We used to return true
in case location
contained RWType::INSERT
and false
otherwise. I believe we should maintain these semantics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That value was never captured in any of the calls and struck me as cruft from other CC implementations but I can change it back.
test/common/lock_free_array_test.cpp
Outdated
{ | ||
LockFreeArray<value_type> array; | ||
|
||
value_type invalid_value = 6288; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use INVALID_OID
instead.
@poojanilangekar Regarding comment 2, there are no tests for transaction_context and for TimestampOrderingTransactionManager, well... :( Maybe I can adapt the tests I wrote for GC fixes to have EXPECTs that test TOTM. It would be helpful to have some sort of baselines if we're making changes to TOTM's guts. For performance, our numbers still seem way too variable to take away anything meaningful, but I'll see if a bunch of runs will smooth that out. |
Like I mentioned, hard to take away too much from oltpbench runs right now due to variability. I ran master and the friday_night branch with the attached configs on my laptop: TPC-C (scale factor 4, 4 terminals, 60 seconds, repeated 10 times): YCSB (scale factor 1000, 4 terminals, read only, 60 seconds, repeated 10 times): |
I also did some sampling with dtrace, configs from the previous comment: TPC-C Sampled calls to StorageManager::GetTileGroup (cuckoo hash lookups) from CommitTransaction: Sampled calls to tbb::internal_find: YCSB read-only Sampled calls to StorageManager::GetTileGroup (cuckoo hash lookups) from CommitTransaction: Sampled calls to tbb::internal_find: |
@mbutrovich Do you have an idea about why the performance of this branch has higher variance? Yes, it would be great if you could add a couple of tests, to the |
@poojanilangekar Luck of the draw with Peloton and oltpbench, really. Also this is on my laptop where I don't have a ton of control over background tasks. I ran them again today: TPC-C (scale factor 4, 4 terminals, 60 seconds, repeated 10 times): YCSB (scale factor 1000, 4 terminals, read only, 60 seconds, repeated 10 times): Again, still tough to take too much away from oltpbench right now. Regarding tests for TOTM, not sure this is the PR for it. I'll put the is_written_ flag back. |
Refactor of RecordDelete to reduce lookups.
might help to get the abort rate reported also ...
…On Wed, Jun 13, 2018 at 3:13 PM Matt Butrovich ***@***.***> wrote:
@poojanilangekar <https://github.com/poojanilangekar> Luck of the draw
with Peloton and oltpbench, really. Also this is on my laptop where I don't
have a ton of control over background tasks. I ran them again today:
*TPC-C (scale factor 4, 4 terminals, 60 seconds, repeated 10 times):*
master: mu: 332.59, sigma: 11.98
friday_night: mu: 333.06, sigma: 13.33
*YCSB (scale factor 1000, 4 terminals, read only, 60 seconds, repeated 10
times):*
master: mu: 16689.99, sigma: 127.87
friday_night: mu: 16706.10, sigma: 122.95
Again, still tough to take too much away from oltpbench right now.
Regarding tests for TOTM, not sure this is the PR for it.
I'll put the is_written_ flag back.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1401 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABS8HLEXnUVFldlKELXUud4RJWi6A6BWks5t8XKBgaJpZM4UjN9u>
.
--
Anthony Tomasic
Language Technologies Institute
Carnegie Mellon University
http://www.tiramisutransit.com
*http://mcds.cs.cmu.edu <http://mcds.cs.cmu.edu>*
http://www.cs.cmu.edu/~tomasic
|
LGTM. I think this should be merged in once the build passes. |
@tomasic I just ran dtrace to approximate abort rates (never tried Peloton's internal stats, and not sure how much they slow the system down). dtrace dropped throughput by ~10%, but: TPC-C: YCSB: It doesn't seem like aborts are an issue, at least under these oltpbench configs on my laptop. |
Thanks - i just wondered because we are off by a factor of 100 for tpc-c
and the function tracing stuff isn’t revealing obvious holes. So now I
suspect locks and latches. Anthony
On Wed, Jun 13, 2018 at 4:28 PM Matt Butrovich ***@***.***> wrote:
@tomasic <https://github.com/tomasic> I just ran dtrace to approximate
abort rates (never tried Peloton's internal stats, and not sure how much
they slow the system down). dtrace dropped throughput by ~10%, but:
*TPC-C:*
CommitTransaction() samples: 27261
AbortTransaction() samples: 1
*YCSB:*
CommitTransaction() samples: 17997
AbortTransaction() samples: 0
It doesn't seem like aborts are an issue, at least under these oltpbench
configs on my laptop.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1401 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABS8HOMB325becreskT-yyYzLfN1TOFBks5t8YQYgaJpZM4UjN9u>
.
--
Anthony Tomasic
Language Technologies Institute
Carnegie Mellon University
http://www.tiramisutransit.com
*http://mcds.cs.cmu.edu <http://mcds.cs.cmu.edu>*
http://www.cs.cmu.edu/~tomasic
|
RWSet performance fixes, LockFreeArray performance fixes and tests
LockFreeArray:
TimestampOrderingTransactionManger:
TransactionContext:
https://software.intel.com/en-us/node/506175
@pervazea is going to help me out and grab callgrind numbers when he has time to demonstrate these improvements.