Dela via


Gör så här: Skriva en parallel_for_each loop

Det här exemplet visar hur du använder algoritmen concurrency::parallel_for_each för att beräkna antalet primtal i ett std::array objekt parallellt.

Exempel

I följande exempel beräknas antalet primtal i en matris två gånger. Exemplet använder först algoritmen std::for_each för att beräkna antalet seriellt. Exemplet använder sedan algoritmen parallel_for_each för att utföra samma uppgift parallellt. Exemplet skriver också ut till konsolen den tid som krävs för att utföra båda beräkningarna.

// parallel-count-primes.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>
#include <algorithm>
#include <array>

using namespace concurrency;
using namespace std;

// Returns the number of milliseconds that it takes to call the passed in function.
template <class Function>
__int64 time_call(Function&& f)
{
    __int64 begin = GetTickCount();
    f();
    return GetTickCount() - begin;
}

// Determines whether the input is a prime.
bool is_prime(int n)
{
    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<int, 200000> a;

    // Initialize the array such that a[i] == i.
    int n = 0;
    generate(begin(a), end(a), [&]
        {
            return n++;
        });

    // 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 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);
                    }
                });
        });

    wcout << L"parallel version: " << endl
        << L"found " << prime_count << L" prime numbers" << endl
        << L"took " << elapsed << L" ms" << endl << endl;
}

Följande exempelutdata är för en dator som har fyra kärnor.

serial version:
found 17984 prime numbers
took 125 ms

parallel version:
found 17984 prime numbers
took 63 ms

Kompilera koden

Om du vill kompilera koden kopierar du den och klistrar sedan in den i ett Visual Studio-projekt eller klistrar in den i en fil med namnet parallel-count-primes.cpp och kör sedan följande kommando i ett Visual Studio-kommandotolkfönster.

cl.exe /EHsc parallel-count-primes.cpp

Robust Programmering

Lambda-uttrycket som exemplet skickar till algoritmen parallel_for_eachInterlockedIncrement använder funktionen för att aktivera parallella iterationer av loopen för att öka räknaren samtidigt. Om du använder funktioner som InterlockedIncrement för att synkronisera åtkomst till delade resurser kan du orsaka prestandaflaskhalsar i din kod. Du kan använda en låsfri synkroniseringsmekanism, till exempel concurrency::combinable klassen, för att eliminera samtidig åtkomst till delade resurser. Ett exempel som använder combinable klassen på det här sättet finns i How to: Use combinable to improve performance (Använda kombinerbart för att förbättra prestanda).

Se även

Parallella algoritmer
parallel_for_each Funktion