void solve_1(std::size_t n) { std::vector<std::future<void>> v; for (std::size_t i = 0; i < n; ++i) { v.emplace_back(std::async(do_something)); } for (auto& f : v) { f.wait(); }}
void solve_2(std::size_t n) { std::atomic_size_t task_count(n); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something(); if (task_count.fetch_sub(1u, std::memory_order_release) == 1u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); } }).detach(); } p.get_future().wait();}
void solve_2(std::size_t n) { std::atomic_size_t task_count(n - 1u); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something(); if (task_count.fetch_sub(1u, std::memory_order_release) == 0u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); } }).detach(); } p.get_future().wait();}
void solve_2(std::size_t n) { std::atomic_size_t task_count(n - 1u); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something(); if (task_count.fetch_sub(1u, std::memory_order_release) == 0u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); } }).detach(); } p.get_future().wait();}
Actually, I haven't submitted the draft for the solution yet because I followed the first instruction on the "How To Submit a Proposal" page. It says only an initial brief description is needed so far.Do you mean that the draft is supposed to be submitted at this stage?
Please be as concise and brief as possible. I don't want you to be discouraged of pursuing your idea, specially considering all the effort you spent, so please focus on these observations so people can quickly spot what are you talking about.
This should take no more than few lines.
Daniel.
Thanks,
Jens
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/58FA1395.7010107%40gmx.net.
On Fri, Apr 21, 2017 at 11:13 AM, Jens Maurer <Jens....@gmx.net> wrote:On 04/21/2017 02:32 PM, Mingxin Wang wrote:
> Actually, I haven't submitted the draft for the solution yet because I followed the first instruction on the "How To Submit a Proposal <https://isocpp.org/std/submit-a-proposal>" page. It says only an initial brief description is needed so far.
>
> Do you mean that the draft is supposed to be submitted at this stage?
I'm not defining the rules, so I can't comment on "supposed".
You have given a long description (which I didn't read in detail),
but I'm missing specific (and preferably short) code examples showing
how to solve some specific problem with your proposed extension.
Showing the contrast of how you would solve the same problem without
using your extension often helps convincing, too.
Mingxin, I will echo Jens and Tony. It is evident that you spent a lot of effort to write the email in a level of detail and beauty few times seen in this list. The issue is, as Jens and Tony mention, that the following items are not obvious or missing:
- Problem statement
- Why it is a problem
- How people is dealing with those problems nowadays (workaround?)
- What your solution is (as Tony suggests, a "before and after" your proposed changes in terms of code, and if possible too, in terms of the standard)
Please be as concise and brief as possible. I don't want you to be discouraged of pursuing your idea, specially considering all the effort you spent, so please focus on these observations so people can quickly spot what are you talking about.
This should take no more than few lines.
Daniel.
Thanks,
Jens
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/58FA1395.7010107%40gmx.net.
template <class Executor>class ExecutorPortal { public: ExecutorPortal(Executor& executor) : executor_(executor) {}
template <class F, class... Args> void operator()(F&& f, Args&&... args) { executor_.execute(std::forward<F>(f), std::forward<Args>(args)...); // Or maybe post or defer }
private: Executor& executor_;};
From: Mingxin Wang Sent: Friday, April 21, 2017 10:27 PM To: ISO C++ Standard - Future Proposals Reply To: std-pr...@isocpp.org Subject: Re: [std-proposals] A Proposal for C++ Concurrency |
void solve(std::size_t n) {
std::atomic_size_t task_count(n); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something(); if (task_count.fetch_sub(1u, std::memory_order_release) == 1u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); } }).detach(); } p.get_future().wait();}
void solve(std::size_t n) {
std::atomic_size_t task_count(n - 1u); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something(); if (task_count.fetch_sub(1u, std::memory_order_release) == 0u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); } }).detach(); } p.get_future().wait();}
void solve(std::size_t n) {
std::atomic_size_t task_count(n - 1u); std::promise<void> p; for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something();
std::atomic_thread_fence(std::memory_order_release); std::size_t cur = task_count.load(std::memory_order_relaxed); do { if (cur == 0u) { std::atomic_thread_fence(std::memory_order_acquire); p.set_value(); break; } } while (!task_count.compare_exchange_weak(cur, cur - 1u, std::memory_order_relaxed)); }).detach(); } p.get_future().wait();}
void solve(std::size_t n) { con::sync_concurrent_invoke( [] {}, con::make_concurrent_caller( n, con::make_concurrent_callable( con::ThreadPortal<true>(), con::make_concurrent_procedure(do_something))));}
void solve(std::size_t n) { con::sync_concurrent_invoke_explicit( con::TreeAtomicCounter<10u>::Initializer(), con::DisposableBinarySemaphore(), [] {}, con::make_concurrent_caller( n, con::make_concurrent_callable( con::ThreadPortal<true>(), con::make_concurrent_procedure(do_something))));}
void solve(std::size_t n) {
std::vector<std::future<void>> v;
for (std::size_t i = 0; i < n; ++i) {
v.emplace_back(std::async(do_something)); } for (auto& f : v) { f.wait(); }}
void solve(std::size_t n) { std::experimental::latch lat(n);
for (std::size_t i = 0; i < n; ++i) { std::thread([&] { do_something();
lat.count_down(); }).detach(); } lat.wait();}
Although they can be used to implement the synchronizations and have nice composability, they are usually not optimal in terms of performance. For example, the "Latches" usually have better performance than the "Futures" in many-to-one synchronizations, as is shown below.
void solve(std::size_t n) {
std::experimental::latch lat(n);for (std::size_t i = 0; i < n; ++i) {std::thread([&] {do_something();lat.count_down();}).detach();}lat.wait();}
Solve with the "Latches