From a5a57868a14da609b90063e4b5926df0c499afcf Mon Sep 17 00:00:00 2001 From: Taojunshen Date: Wed, 14 Sep 2022 01:27:07 +0800 Subject: [PATCH] optimize prime test (#4515) Co-authored-by: TylerMSFT Co-authored-by: Bryan Gold <101299717+19BMG00@users.noreply.github.com> --- ...ow-to-write-a-parallel-for-each-loop_1.cpp | 106 ++++++++++-------- .../how-to-write-a-parallel-for-each-loop.md | 25 ++--- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/docs/parallel/concrt/codesnippet/CPP/how-to-write-a-parallel-for-each-loop_1.cpp b/docs/parallel/concrt/codesnippet/CPP/how-to-write-a-parallel-for-each-loop_1.cpp index d29a9cf0d7c..f6008df0639 100644 --- a/docs/parallel/concrt/codesnippet/CPP/how-to-write-a-parallel-for-each-loop_1.cpp +++ b/docs/parallel/concrt/codesnippet/CPP/how-to-write-a-parallel-for-each-loop_1.cpp @@ -9,66 +9,78 @@ using namespace concurrency; using namespace std; -// Calls the provided work function and returns the number of milliseconds -// that it takes to call that function. +// Returns the number of milliseconds that it takes to call the passed in function. template __int64 time_call(Function&& f) { - __int64 begin = GetTickCount(); - f(); - return GetTickCount() - begin; + __int64 begin = GetTickCount(); + f(); + return GetTickCount() - begin; } -// Determines whether the input value is prime. +// Determines whether the input is a prime. bool is_prime(int n) { - if (n < 2) - return false; - for (int i = 2; i < n; ++i) - { - if ((n % i) == 0) - return false; - } - return true; + if (n < 2) + { + return false; + } + + for (int i = 2; i < int(std::sqrt(n)) + 1; ++i) + { + if (n % i == 0) + { + return false; + } + } + return true; } int wmain() { - // Create an array object that contains 200000 integers. - array a; + // Create an array object that contains 200000 integers. + array a; - // Initialize the array such that a[i] == i. - int n = 0; - generate(begin(a), end(a), [&] { - return n++; - }); + // Initialize the array such that a[i] == i. + int n = 0; + generate(begin(a), end(a), [&] + { + return n++; + }); - LONG prime_count; - __int64 elapsed; + // Use the for_each algorithm to count, serially, the number + // of prime numbers in the array. + LONG prime_count = 0L; + __int64 elapsed = time_call([&] + { + for_each(begin(a), end(a), [&](int n) + { + if (is_prime(n)) + { + ++prime_count; + } + }); + }); + + wcout << L"serial version: " << endl + << L"found " << prime_count << L" prime numbers" << endl + << L"took " << elapsed << L" ms" << endl << endl; - // Use the for_each algorithm to count the number of prime numbers - // in the array serially. - prime_count = 0L; - elapsed = time_call([&] { - for_each (begin(a), end(a), [&](int n ) { - if (is_prime(n)) - ++prime_count; - }); - }); - wcout << L"serial version: " << endl - << L"found " << prime_count << L" prime numbers" << endl - << L"took " << elapsed << L" ms" << endl << endl; + // Use the parallel_for_each algorithm to count, in parallel, the number + // of prime numbers in the array. + prime_count = 0L; + elapsed = time_call([&] + { + parallel_for_each(begin(a), end(a), [&](int n) + { + if (is_prime(n)) + { + InterlockedIncrement(&prime_count); + } + }); + }); - // Use the parallel_for_each algorithm to count the number of prime numbers - // in the array in parallel. - prime_count = 0L; - elapsed = time_call([&] { - parallel_for_each (begin(a), end(a), [&](int n ) { - if (is_prime(n)) - InterlockedIncrement(&prime_count); - }); - }); - wcout << L"parallel version: " << endl - << L"found " << prime_count << L" prime numbers" << endl - << L"took " << elapsed << L" ms" << endl << endl; + wcout << L"parallel version: " << endl + << L"found " << prime_count << L" prime numbers" << endl + << L"took " << elapsed << L" ms" << endl << endl; } \ No newline at end of file diff --git a/docs/parallel/concrt/how-to-write-a-parallel-for-each-loop.md b/docs/parallel/concrt/how-to-write-a-parallel-for-each-loop.md index d7a5805ed78..3351136b798 100644 --- a/docs/parallel/concrt/how-to-write-a-parallel-for-each-loop.md +++ b/docs/parallel/concrt/how-to-write-a-parallel-for-each-loop.md @@ -1,30 +1,29 @@ --- -description: "Learn more about: How to: Write a parallel_for_each Loop" -title: "How to: Write a parallel_for_each Loop" -ms.date: "11/04/2016" +description: "Learn more about how to write a parallel_for_each Loop" +title: "How to: write a parallel_for_each Loop" +ms.date: 09/12/2022 helpviewer_keywords: ["writing a parallel_for_each loop [Concurrency Runtime]", "parallel_for_each function, example"] -ms.assetid: fa9c0ba6-ace0-4f88-8681-c7c1f52aff20 --- -# How to: Write a parallel_for_each Loop +# How to: Write a `parallel_for_each` Loop -This example shows how to use the [concurrency::parallel_for_each](reference/concurrency-namespace-functions.md#parallel_for_each) algorithm to compute the count of prime numbers in a [std::array](../../standard-library/array-class-stl.md) object in parallel. +This example shows how to use the [`concurrency::parallel_for_each`](reference/concurrency-namespace-functions.md#parallel_for_each) algorithm to compute the count of prime numbers in a [`std::array`](../../standard-library/array-class-stl.md) object in parallel. ## Example -The following example computes the count of prime numbers in an array two times. The example first uses the [std::for_each](../../standard-library/algorithm-functions.md#for_each) algorithm to compute the count serially. The example then uses the `parallel_for_each` algorithm to perform the same task in parallel. The example also prints to the console the time that is required to perform both computations. +The following example computes the count of prime numbers in an array two times. The example first uses the [`std::for_each`](../../standard-library/algorithm-functions.md#for_each) algorithm to compute the count serially. The example then uses the `parallel_for_each` algorithm to perform the same task in parallel. The example also prints to the console the time that is required to perform both computations. [!code-cpp[concrt-parallel-count-primes#1](../../parallel/concrt/codesnippet/cpp/how-to-write-a-parallel-for-each-loop_1.cpp)] -The following sample output is for a computer that has four processors. +The following sample output is for a computer that has four cores. ```Output serial version: found 17984 prime numbers -took 6115 ms +took 125 ms parallel version: found 17984 prime numbers -took 1653 ms +took 63 ms ``` ## Compiling the Code @@ -35,9 +34,9 @@ To compile the code, copy it and then paste it in a Visual Studio project, or pa ## Robust Programming -The lambda expression that the example passes to the `parallel_for_each` algorithm uses the `InterlockedIncrement` function to enable parallel iterations of the loop to increment the counter simultaneously. If you use functions such as `InterlockedIncrement` to synchronize access to shared resources, you can present performance bottlenecks in your code. You can use a lock-free synchronization mechanism, for example, the [concurrency::combinable](../../parallel/concrt/reference/combinable-class.md) class, to eliminate simultaneous access to shared resources. For an example that uses the `combinable` class in this manner, see [How to: Use combinable to Improve Performance](../../parallel/concrt/how-to-use-combinable-to-improve-performance.md). +The lambda expression that the example passes to the `parallel_for_each` algorithm uses the `InterlockedIncrement` function to enable parallel iterations of the loop to increment the counter simultaneously. If you use functions such as `InterlockedIncrement` to synchronize access to shared resources, you can present performance bottlenecks in your code. You can use a lock-free synchronization mechanism, for example, the [`concurrency::combinable`](../../parallel/concrt/reference/combinable-class.md) class, to eliminate simultaneous access to shared resources. For an example that uses the `combinable` class in this manner, see [How to: Use combinable to improve performance](../../parallel/concrt/how-to-use-combinable-to-improve-performance.md). ## See also -[Parallel Algorithms](../../parallel/concrt/parallel-algorithms.md)
-[parallel_for_each Function](reference/concurrency-namespace-functions.md#parallel_for_each) +[Parallel algorithms](../../parallel/concrt/parallel-algorithms.md)\ +[`parallel_for_each` Function](reference/concurrency-namespace-functions.md#parallel_for_each)