-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add topic about "Lazy Initiliazation" pattern to Design patterns #790
Changes from 12 commits
01d69b0
b3b01c1
d613740
928f7a2
3549d82
6312add
7baf419
898b23a
957ec11
6f47751
5ebd730
e36e72b
695fc00
6916ca5
6f1475d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,97 @@ | ||||||
.. _Lazy_Initialization: | ||||||
|
||||||
Lazy Initialization | ||||||
================== | ||||||
|
||||||
|
||||||
.. container:: section | ||||||
|
||||||
|
||||||
.. rubric:: Problem | ||||||
:class: sectiontitle | ||||||
|
||||||
Delay the creation of an object (potentially expensive) until it is accessed. | ||||||
In parallel programming initialization also must be guarded against race conditions. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||
|
||||||
|
||||||
.. container:: section | ||||||
|
||||||
|
||||||
.. rubric:: Context | ||||||
:class: sectiontitle | ||||||
|
||||||
The cost of operations that take place during the initialization | ||||||
of the object may be considerably high. In that case, the object | ||||||
should be initialized only when it is needed. Lazy initialization | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done (also applicable to the comments below). |
||||||
is the common tactic that allows implementing such approach. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||
|
||||||
|
||||||
.. container:: section | ||||||
|
||||||
|
||||||
.. rubric:: Solution | ||||||
:class: sectiontitle | ||||||
|
||||||
Using ``oneapi::tbb::collaborative_call_once`` with ``oneapi::tbb::collaborative_once_flag`` | ||||||
helps to implement thread-safe lazy initialization for a user object. | ||||||
|
||||||
|
||||||
In addition, ``collaborative_call_once`` allows other thread blocked on | ||||||
the same ``collaborative_once_flag`` to join other |short_name| | ||||||
parallel constructions called within the initializing function. | ||||||
|
||||||
|
||||||
.. container:: section | ||||||
|
||||||
|
||||||
.. rubric:: Example | ||||||
:class: sectiontitle | ||||||
|
||||||
The example presented here illustrate implementation of "lazy initialization" for Fibonacci numbers calculation. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is lazy initialization in quotes here but not in the cases above? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed quotes. |
||||||
Here is a graphical representation of the Fibonacci recursion tree for N=4. | ||||||
|
||||||
|
||||||
|image0| | ||||||
|
||||||
|
||||||
As seen in the diagram, some elements are recalculated more than once. These operations are redundant, | ||||||
so the "lazy initialized" Fibonacci numbers are relevant here. | ||||||
|
||||||
|
||||||
The code for the implementation is shown below. Already calculated values are stored in a buffer paired with | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
``collaborative_once_flag`` and won't be recalculated when ``collaborative_call_once`` is invoked | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
when initialization has already been done. | ||||||
|
||||||
|
||||||
:: | ||||||
|
||||||
|
||||||
using FibBuffer = std::vector<std::pair<oneapi::tbb::collaborative_once_flag, std::uint64_t>>; | ||||||
|
||||||
std::uint64_t LazyFibHelper(int n, FibBuffer& buffer) { | ||||||
// Base case | ||||||
if (n <= 1) { | ||||||
return n; | ||||||
} | ||||||
// Calculate nth value only once and store it in the buffer. | ||||||
// Other threads won't be blocked on already taken collaborative_once_flag | ||||||
// but join parallelism inside functor | ||||||
oneapi::tbb::collaborative_call_once(buffer[n].first, [&]() { | ||||||
std::uint64_t a, b; | ||||||
oneapi::tbb::parallel_invoke([&] { a = LazyFibHelper(n - 2, buffer); }, | ||||||
[&] { b = LazyFibHelper(n - 1, buffer); }); | ||||||
buffer[n].second = a + b; | ||||||
}); | ||||||
|
||||||
return buffer[n].second; | ||||||
} | ||||||
|
||||||
std::uint64_t Fib(int n) { | ||||||
FibBuffer buffer(n+1); | ||||||
return LazyFibHelper(n, buffer); | ||||||
} | ||||||
|
||||||
|
||||||
.. |image0| image:: Images/image008a.jpg | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you remake screenshots so it would have a space above and beneath the figures? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated images. |
||||||
:width: 740px | ||||||
:height: 344px |
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.
Done.