Aracılığıyla paylaş


Nasıl yapılır: harita gerçekleştirmek ve paralel işlemleri azaltma

Bu örnek, nasıl kullanılacağını gösterir concurrency::parallel_transform ve concurrency::parallel_reduce algoritmaları ve concurrency::concurrent_unordered_map dosyalarında sözcük kaç kez yinelendiğini saymak için sınıf.

A Harita işlem dizisindeki her değer için bir işlevi uygulanır.A azaltmak işlem sırası içine bir değer öğelerini birleştirir.Standart şablon kitaplığı (stl) kullanabilirsiniz std::transformstd::accumulate işlemleri azaltmak ve harita gerçekleştirmek için sınıflar.Ancak, birçok sorunları performansını artırmak için kullanabileceğiniz parallel_transform paralel olarak eşleme işlemi gerçekleştirmek için kullanılan algoritma ve parallel_reduce paralel olarak küçültme işlemi gerçekleştirmek için bir algoritma.Bazı durumlarda kullanabileceğiniz concurrent_unordered_map harita ve küçültme bir işlemi gerçekleştirmek için.

Örnek

Aşağıdaki örnek, dosyalarında sözcük oluşumlarını sayar.Kullandığı std::vector iki dosya içeriğini göstermek için.Eşleme işlemi, her sözcüğün her vektör kaç kez yinelendiğini hesaplar.Küçültme işlemi hem vektör sözcük sayıları birikir.

// parallel-map-reduce.cpp
// compile with: /EHsc
#include <ppl.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <numeric>
#include <unordered_map>
#include <windows.h>

using namespace concurrency;
using namespace std;

class MapFunc 
{ 
public:
    unordered_map<wstring, size_t> operator()(vector<wstring>& elements) const 
    { 
        unordered_map<wstring, size_t> m;
        for_each(begin(elements), end(elements), [&m](const wstring& elem)
        { 
            m[elem]++;
        });
        return m; 
    }
}; 

struct ReduceFunc : binary_function<unordered_map<wstring, size_t>, 
                    unordered_map<wstring, size_t>, unordered_map<wstring, size_t>>
{
    unordered_map<wstring, size_t> operator() (
        const unordered_map<wstring, size_t>& x, 
        const unordered_map<wstring, size_t>& y) const
    {
        unordered_map<wstring, size_t> ret(x);
        for_each(begin(y), end(y), [&ret](const pair<wstring, size_t>& pr) {
            auto key = pr.first;
            auto val = pr.second;
            ret[key] += val;
        });
        return ret; 
    }
}; 

int wmain()
{ 
    // File 1 
    vector<wstring> v1;
    v1.push_back(L"word1"); //1 
    v1.push_back(L"word1"); //2 
    v1.push_back(L"word2"); 
    v1.push_back(L"word3"); 
    v1.push_back(L"word4"); 

    // File 2 
    vector<wstring> v2; 
    v2.push_back(L"word5"); 
    v2.push_back(L"word6"); 
    v2.push_back(L"word7"); 
    v2.push_back(L"word8"); 
    v2.push_back(L"word1"); //3 

    vector<vector<wstring>> v;
    v.push_back(v1);
    v.push_back(v2);

    vector<unordered_map<wstring, size_t>> map(v.size()); 

    // The Map operation
    parallel_transform(begin(v), end(v), begin(map), MapFunc()); 

    // The Reduce operation 
    unordered_map<wstring, size_t> result = parallel_reduce(
        begin(map), end(map), unordered_map<wstring, size_t>(), ReduceFunc());

    wcout << L"\"word1\" occurs " << result.at(L"word1") << L" times. " << endl;
} 
/* Output:
   "word1" occurs 3 times.
*/

Kod Derleniyor

Kodu derlemek için kopyalayın ve sonra Visual Studio Project'te yapıştırın veya adlı bir dosyaya yapıştırın paralel harita reduce.cpp ve Visual Studio komut istemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc parallel-map-reduce.cpp

Güçlü Programlama

Bu örnekte, kullanabileceğiniz concurrent_unordered_map sınıfı — concurrent_unordered_map.h—to içinde tanımlanan eşlem gerçekleştirmek ve tek bir işlemde azaltmak.

// File 1 
vector<wstring> v1;
v1.push_back(L"word1"); //1 
v1.push_back(L"word1"); //2 
v1.push_back(L"word2"); 
v1.push_back(L"word3"); 
v1.push_back(L"word4"); 

// File 2 
vector<wstring> v2; 
v2.push_back(L"word5"); 
v2.push_back(L"word6"); 
v2.push_back(L"word7"); 
v2.push_back(L"word8"); 
v2.push_back(L"word1"); //3 

vector<vector<wstring>> v;
v.push_back(v1);
v.push_back(v2);

concurrent_unordered_map<wstring, size_t> result;
for_each(begin(v), end(v), [&result](const vector<wstring>& words) {
    parallel_for_each(begin(words), end(words), [&result](const wstring& word) {
        InterlockedIncrement(&result[word]);
    });
});

wcout << L"\"word1\" occurs " << result.at(L"word1") << L" times. " << endl;

/* Output:
   "word1" occurs 3 times.
*/

Genellikle, yalnızca dış veya iç döngü parallelize.İç döngü, nispeten daha az sayıda dosya varsa ve her dosyayı çok sözcük içeren parallelize.Göreceli olarak çok sayıda dosya varsa ve her dosya birkaç sözcük varsa dış döngü parallelize.

Ayrıca bkz.

Başvuru

parallel_transform işlevi

parallel_reduce işlevi

concurrent_unordered_map sınıfı

Kavramlar

Paralel algoritmalar