1. 程式人生 > >Visual Studio 11開發指南(19)C++11更新-並行模式庫和代理庫

Visual Studio 11開發指南(19)C++11更新-並行模式庫和代理庫

                 Visual Studio 11,具備並行模式庫代理庫、 更輕鬆地開發多核處理器上執行的並行程式碼。

這些庫的主要範例是根據任務 和併發執行庫,自定義的排程程式 進行處理的。

到目前為止,處理任務的的概念原型,就使用task_handle ●型別 如下所示:

1.task_group task;     2.    int i=0;     3.    auto  t1=make_task([&i]() 4.        { 5.             6.            i=427.        }); 8.    int z=09.    auto t2=make_task([&z]() 10.        { 11.
             12.            z=4213.        }); 14.  15.    task.run_and_wait (t1);     16.    task.run_and_wait (t2);     17.    std::wcout << i+z << std::endl18.    std::wcout << "Fini" << std::endl;

這裡計算的 i + z 是必須得到的 lambda 表示式中引用變數 。然後這兩個任務並行完成它們的工作。

使用 Visual Studio 11,可以直接使用的task

型別的概念,如下所示:

1.task<int> t1=task<int>([]()->int 2.        { 3.            return 424.        }); 5.     6.    task<int> t2=task<int>([]()->int 7.        { 8.            return 429.        }); 10.     11.    std::wcout << t1.get() +t2.get () << std::endl;

為了簡化語法,更需要為每項任務捕獲變數的引用,要通過呼叫方法wait()

的每個任務並返回值角色的方法get (),獲取狀態以便處理

task類的非同步任務的遵循設定的執行規則,無需等待,即是說,不論Tn 取決於 Tn-1 任務的任務以及前一任務已完成或沒有。

非同步操作將概括為避免假死的使用者介面,很重要的是為了簡化開發過程,以前的VS經常卡死,載入控制元件的時候。

若要實現這一概念,task類實現的then()方法,將會執行一次已經完成後的該任務。

1.task<int> t1=task<int>([]()->int 2.    { 3.        return 424.    }).then ([](int i)->int 5.        { 6.         7.            return i+42;     8.        }); 9.  10.task<int> t2=task<int>([]()->int 11.    { 12.        //simule une charge 13.        std::this_thread::sleep_for (chrono::seconds (1));         14.        return 4215.    }).then ([](int i)->int 16.        { 17.             18.            return i+42;     19.        });             20.std::wcout << t1.get() + t2.get() << std::endl;

每項任務的返回值是作為引數傳遞,例如lambda 表示式中的then()方法。

並行演算法還包括 (parallel_for、 parallel_for_each、 parallel_invoke ))

並行演算法的嘗試

parallel_sortparallel_radixsortparallel_buffered_sort的標準如果命令它只執行並行模式,其中使用演算法的方式都相同。

1.vector<unsigned int> v3; 2.   parallel_sort(begin(v3),end(v3))

雖然在大多數情況下,這是一個簡單的類整數的效能足夠流暢了(示例向量的整數 40 000 000,得到一個序列(std::sort)parallel_sort(),允許更好地調控,會提高效能)

每種演算法,都用來做過載,這個方法允許設定的字串的排序和要使用的分割槽的大小。

1.vector<unsigned int> v2; 2.      parallel_sort(begin(v2),end(v2),[](const unsigned int& l,const unsigned int& r)->bool     3.   { 4.        5.       return (l<r); 6.   },4096);   

預設分割槽大小為 2048,對於大多數情況下就足夠了。可以調整最後一個分割槽的大小來提高效能。如果分割槽大小《=向量的大小,將使用任何方法std::sort ()中。(預設情況下,如果向量的元素的數目 < = 2048總是使用std::sort ()版本)。

1.inline void parallel_sort(const _Random_iterator &_Begin, const _Random_iterator &_End, const _Function &_Func, const size_t _Chunk_size = 2048) 2.3.    _CONCRT_ASSERT(_Chunk_size > 0); 4.  5.    // We make the guarantee that if the sort is part of a tree that has been canceled before starting, it will 6.    // not begin at all. 7.    if (is_current_task_group_canceling()) 8.    { 9.        return10.    } 11.  12.    size_t _Size = _End - _Begin; 13.    size_t _Core_num = Concurrency::details::_CurrentScheduler::_GetNumberOfVirtualProcessors(); 14.  15.    if (_Size <= _Chunk_size || _Core_num < 216.    { 17.        return std::sort(_Begin, _End, _Func); 18.    } 19.  20.    _Parallel_quicksort_impl(_Begin, _Size, _Func, _Core_num * _MAX_NUM_TASKS_PER_CORE, _Chunk_size, 0); 21.}

系統至少不會以任何方式使用 std::sort () 的虛擬處理器。

可用其他演算法的嘗試並根據實際需要。例如,在例子中的是基數排序

1.vector<unsigned int> v4; 2.   parallel_radixsort(begin(v4),end(v4));

提供更好的結果 197.09 上 40 000 000 個專案。預設分割槽大小為 256 * 256

parallel_buffered_sort給 631

1. parallel_buffered_sort(begin(v5),end(v5));

減少

執行緒申請的數量,最小,最多的一組所有成員稱為一般減少。應用減少並行可以或者涉及爭用條件或問題的另外的浮點操作的舍入為例。

例如雙平行處理的迴圈,迴圈的量的一種方法是使用concurrency::combinable <T>物件

1.combinable<double> sumReduction;     2.   parallel_for_each(begin(v1),end(v1),[&sumReduction](double i) 3.   {      4.       sumReduction.local ()+=i;        5.   }); 6.   sum=sumReduction.combine (std::plus<double>());

Visual Studio 11,現在可以使用演算法parallel_reduce(),比型別演算法的使用效率更高(concurrency::combinable)。

它的使用是相對處理演算法( std::accumulate)

vector<double>::const_iterator deb=begin(v1); 2.   vector<double>::const_iterator fin=end(v1); 3.   auto identity=std::iterator_traits<vector<double>::const_iterator>::value_type();    4.   sum= parallel_reduce(deb,fin,identity,std::plus<double>());

轉型

最後的演算法是加工parallel_transformation()演算法

1.parallel_transform(begin(v1),end(v1),begin(v2),[](double value)->double 2.{ 3.    return value*2; 4.});