Некоторое время назад я писал в блоге о проблемах (см. запись "OpenMP и исключения (exceptions)"), которые возникают при выходе исключения за пределы параллельных регионах. В том числе я рассказал, что исключение может быть сгенерировано оператором new и его необходимо обязательно перехватить и обработать до того, как оно покинет параллельный регион. Конструкции для этого выглядят достаточно неудобно и громоздко. И не так давно мне написали, что в данном случае более изящным решением будет использование оператора new, не генерирующего исключения. То есть использование "nothrow"-варианта оператора new, который возвращает NULL в случае неудачи, позволяет писать более простой OpenMP код.
Для знакомства с оператором new, не генерирующем исключений я отсылаю вас к статье "Nothrow new". А здесь просто приведу два примера, который достаточно ясно продемонстрируют общую идею.
Код с обработкой исключения:
size_t errCount = 0;
#pragma omp parallel for num_threads(4) reduction(+: errCount)
for(int i = 0; i < 4; i++)
{
try {
float *ptr = new float[10000];
// code
delete [] ptr;
}
catch (std::bad_alloc &)
{
++errCount;
}
}
Упрощенный код без обработки исключений:
size_t errCount = 0;
#pragma omp parallel for num_threads(4) reduction(+: errCount)
for(int i = 0; i < 4; i++)
{
float *ptr = new(std::nothrow) float[10000];
if (ptr == NULL) {
++errCount;
} else {
// code
delete [] ptr;
}
}