Skip to content

Conversation

@bkietz
Copy link

@bkietz bkietz commented Feb 17, 2021

No description provided.

pitrou and others added 2 commits February 9, 2021 18:26
Implement a LRU cache, and associated memoization factories.

The simple thread-safe memoization ends up 2x to 3x slower than a thread-unsafe memoization,
in part because the thread-safe memoization has to copy the return value.

Therefore, it can be more desirable to use the thread-unsafe memoization with a thread_local specifier.

Benchmarks (arg 1: key size, arg 2: value size):
```
LRUCacheLookup/8/16                        1877 ns         1877 ns       359452 items_per_second=53.2795M/s
LRUCacheLookup/8/1024                      1924 ns         1924 ns       367765 items_per_second=51.9831M/s
LRUCacheLookup/64/16                       2629 ns         2628 ns       264012 items_per_second=38.0487M/s
LRUCacheLookup/64/1024                     2671 ns         2671 ns       264135 items_per_second=37.4432M/s

MemoizeLRUCached/8/16                      4922 ns         4921 ns       141748 items_per_second=20.3205M/s
MemoizeLRUCached/8/1024                    5688 ns         5687 ns       119853 items_per_second=17.5833M/s
MemoizeLRUCached/64/16                     5347 ns         5347 ns       129134 items_per_second=18.7031M/s
MemoizeLRUCached/64/1024                   6318 ns         6318 ns       110366 items_per_second=15.829M/s

MemoizeLRUCachedThreadUnsafe/8/16          2156 ns         2156 ns       321327 items_per_second=46.3885M/s
MemoizeLRUCachedThreadUnsafe/8/1024        2165 ns         2165 ns       322995 items_per_second=46.1982M/s
MemoizeLRUCachedThreadUnsafe/64/16         3110 ns         3110 ns       225295 items_per_second=32.1552M/s
MemoizeLRUCachedThreadUnsafe/64/1024       3084 ns         3084 ns       225891 items_per_second=32.4268M/s
```
@github-actions
Copy link

Thanks for opening a pull request!

Could you open an issue for this pull request on JIRA?
https://issues.apache.org/jira/browse/ARROW

Then could you also rename pull request title in the following format?

ARROW-${JIRA_ID}: [${COMPONENT}] ${SUMMARY}

See also:

}

private:
std::unique_ptr<std::mutex> mutex_;
Copy link
Owner

Choose a reason for hiding this comment

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

The unique_ptr was meant to make the memoizer type movable. While moving isn't strictly required, non-movable types are generally annoying to use (especially as some compilers may not always implement return value optimization properly).

@pitrou pitrou force-pushed the ARROW-10655-lru-cache branch 3 times, most recently from aedc40e to 43ae445 Compare February 18, 2021 19:47
@pitrou pitrou closed this Feb 19, 2021
@bkietz bkietz deleted the ARROW-10655-lru-cache branch February 19, 2021 18:48
pitrou added a commit that referenced this pull request Apr 7, 2021
From a deadlocked run...

```
#0  0x00007f8a5d48dccd in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00007f8a5d486f05 in pthread_mutex_lock () from /lib64/libpthread.so.0
#2  0x00007f8a566e7e89 in arrow::internal::FnOnce<void ()>::FnImpl<arrow::Future<Aws::Utils::Outcome<Aws::S3::Model::ListObjectsV2Result, Aws::S3::S3Error> >::Callback<arrow::fs::(anonymous namespace)::TreeWalker::ListObjectsV2Handler> >::invoke() () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#3  0x00007f8a5650efa0 in arrow::FutureImpl::AddCallback(arrow::internal::FnOnce<void ()>) () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#4  0x00007f8a566e67a9 in arrow::fs::(anonymous namespace)::TreeWalker::ListObjectsV2Handler::SpawnListObjectsV2() () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#5  0x00007f8a566e723f in arrow::fs::(anonymous namespace)::TreeWalker::WalkChild(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int) () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#6  0x00007f8a566e827d in arrow::internal::FnOnce<void ()>::FnImpl<arrow::Future<Aws::Utils::Outcome<Aws::S3::Model::ListObjectsV2Result, Aws::S3::S3Error> >::Callback<arrow::fs::(anonymous namespace)::TreeWalker::ListObjectsV2Handler> >::invoke() () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#7  0x00007f8a5650efa0 in arrow::FutureImpl::AddCallback(arrow::internal::FnOnce<void ()>) () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#8  0x00007f8a566e67a9 in arrow::fs::(anonymous namespace)::TreeWalker::ListObjectsV2Handler::SpawnListObjectsV2() () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#9  0x00007f8a566e723f in arrow::fs::(anonymous namespace)::TreeWalker::WalkChild(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int) () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
#10 0x00007f8a566e74b1 in arrow::fs::(anonymous namespace)::TreeWalker::DoWalk() () from /arrow/r/check/arrow.Rcheck/arrow/libs/arrow.so
```

The callback `ListObjectsV2Handler` is being called recursively and the mutex is non-reentrant thus deadlock.

To fix it I got rid of the mutex on `TreeWalker` by using `arrow::util::internal::TaskGroup` instead of manually tracking the #/status of in-flight requests.

Closes apache#9842 from westonpace/bugfix/arrow-12040

Lead-authored-by: Weston Pace <weston.pace@gmail.com>
Co-authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants