Aracılığıyla paylaş


Nasıl yapılır: Eşzamanlılık Çalışma Zamanı Kullanmak için Özel Durum İşleme Kullanan bir OpenMP Döngüsünü Dönüştürme

Bu örnekte, Eşzamanlılık Çalışma Zamanı özel durum işleme mekanizmasını kullanmak üzere özel durum işleme gerçekleştiren bir Döngü için OpenMP paralelininnasıl dönüştürüldüğü gösterilmektedir.

OpenMP'de, paralel bölgede oluşan bir özel durum yakalanmalı ve aynı iş parçacığı tarafından aynı bölgede işlenmelidir. Paralel bölgeden kaçan bir özel durum, işlemi varsayılan olarak sonlandıran işlenmeyen özel durum işleyicisi tarafından yakalanıyor.

Eşzamanlılık Çalışma Zamanı'nda, bir iş işlevinin gövdesinde eşzamanlılık::task_group veya eşzamanlılık::structured_task_group nesnesi gibi bir görev grubuna veya eşzamanlılık::p arallel_for gibi paralel bir algoritmaya geçirdiğiniz bir özel durum oluşturduğunuzda, çalışma zamanı bu özel durumu depolar ve görev grubunun veya algoritmanın bitmesini bekleyen bağlama göre sıralar. Görev grupları için bekleme bağlamı eşzamanlılık::task_group::wait, eşzamanlılık::structured_task_group::wait, eşzamanlılık::task_group::run_and_wait veya eşzamanlılık::structured_task_group::run_and_wait çağıran bağlamdır. Paralel algoritma için, bekleme bağlamı bu algoritmayı çağıran bağlamdır. Çalışma zamanı, alt görev gruplarındakiler de dahil olmak üzere görev grubundaki tüm etkin görevleri de durdurur ve henüz başlatılmamış görevleri atar.

Örnek

Bu örnek, bir OpenMP parallel bölgesinde ve çağrısında parallel_forözel durumların nasıl işleneceğini gösterir. İşlevdo_work, başarılı olmayan bir bellek ayırma isteği gerçekleştirir ve bu nedenle std::bad_alloc türünde bir özel durum oluşturur. OpenMP kullanan sürümde, özel durum oluşturan iş parçacığının da onu yakalaması gerekir. Başka bir deyişle, OpenMP paralel döngüsünün her yinelemesi özel durumu işlemelidir. Eşzamanlılık Çalışma Zamanı'nı kullanan sürümde, ana iş parçacığı başka bir iş parçacığı tarafından oluşan bir özel durum yakalar.

// concrt-omp-exceptions.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <new>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

// Demonstrates a function that performs a memory allocation request 
// that does not succeed.
void do_work(int)
{
   // The following memory allocation causes this function to 
   // throw std::bad_alloc.
   char* ptr = new char[(~unsigned int((int)0)/2) - 1];

   // TODO: Assuming that the allocation succeeds, perform some work 
   // and free the allocated memory.

   delete[] ptr;
}

// Demonstrates an OpenMP parallel loop that performs exception handling.
void omp_exception_handling()
{
   #pragma omp parallel for 
      for(int i = 0; i < 10; i++) 
      {
         try {
            // Perform a unit of work.
            do_work(i);
         }
         catch (exception const& e) {
            // Print the error to the console.
            wstringstream ss;
            ss << L"An error of type '" << typeid(e).name() 
               << L"' occurred." << endl;
            wcout << ss.str();
         }
      }
}

// Demonstrates an Concurrency Runtime parallel loop that performs exception handling.
void concrt_exception_handling()
{
   try {
      parallel_for(0, 10, [](int i) 
      {
         // Perform a unit of work.
         do_work(i);
      });
   }
   catch (exception const& e) {
      // Print the error to the console.
      wcout << L"An error of type '" << typeid(e).name() 
            << L"' occurred." << endl;
   }
}

int wmain()
{
   wcout << L"Using OpenMP..." << endl;
   omp_exception_handling();

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_exception_handling();
}

Bu örnek aşağıdaki çıkışı oluşturur.

Using OpenMP...
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
An error of type 'class std::bad_alloc' occurred.
Using the Concurrency Runtime...
An error of type 'class std::bad_alloc' occurred.

Bu örneğin OpenMP kullanan sürümünde, özel durum içinde gerçekleşir ve her döngü yinelemesi tarafından işlenir. Eşzamanlılık Çalışma Zamanı'nı kullanan sürümde çalışma zamanı özel durumu depolar, tüm etkin görevleri durdurur, henüz başlatılmamış görevleri atar ve özel durumu çağıran parallel_forbağlama göre sıralar.

Özel durum oluştuktan sonra OpenMP kullanan sürümün sona ermesi gerekiyorsa, hatanın oluştuğuna ilişkin diğer döngü yinelemelerine sinyal vermek için boole bayrağı kullanabilirsiniz. Nasıl yapılır: Eşzamanlılık Çalışma Zamanını Kullanmak için İptal Kullanan Bir OpenMP Döngüsünü Dönüştürme başlığındaki örnekte olduğu gibi, bayrak ayarlanırsa sonraki döngü yinelemeleri hiçbir şey yapmaz. Buna karşılık, Eşzamanlılık Çalışma Zamanı'nı kullanan döngünün özel durum oluştuktan sonra devam etmesi gerekiyorsa, paralel döngü gövdesindeki özel durumu işleyin.

Eşzamanlılık Çalışma Zamanı'nın zaman uyumsuz aracılar ve basit görevler gibi diğer bileşenleri özel durumları taşımaz. Bunun yerine, işlenmeyen özel durumlar, işlemi varsayılan olarak sonlandıran işlenmeyen özel durum işleyicisi tarafından yakalanılır. Özel durum işleme hakkında daha fazla bilgi için bkz . Özel Durum İşleme.

ve diğer paralel algoritmalar hakkında parallel_for daha fazla bilgi için bkz . Paralel Algoritmalar.

Kod Derleniyor

Örnek kodu kopyalayıp bir Visual Studio projesine yapıştırın veya adlı concrt-omp-exceptions.cpp bir dosyaya yapıştırın ve ardından bir Visual Studio Komut İstemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc /openmp concrt-omp-exceptions.cpp

Ayrıca bkz.

OpenMP döngüsünden Eşzamanlılık Çalışma Zamanına geçiş
Özel Durum İşleme
Paralel Algoritmalar