[SOLVED] TBB and floating point exceptions

[SOLVED] TBB and floating point exceptions

Portrait de Anders W. K.

Hi,

I'm having some trouble using floating point exceptions (FPE) with TBB in release mode. Basically when an FPE happens I want my program to show the windows crash dialog with the option to attach a debugger.  This works fine for programs compiled in debug mode for FPE both inside and outside TBB algorithms. For release mode builds FPE outside TBB algorithms also produce the desired crash, but for FPE inside TBB the error is translated into a C++ exception, which seems inconsistent.

So:

debug mode + outside parallel_for: crash dialog

debug mode + inside parallel_for: crash dialog

release mode + outside parallel_for: crash dialog

release mode + inside parallel_for: unknown exception thrown!

How do I avoid TBB translating my FPE to a C++ exception?

Kind regards

Anders

extern float bar = -1.f;
int main(int argc, char* argv[])
{
_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK()
& ~(_MM_MASK_INVALID|
 _MM_MASK_OVERFLOW |
 _MM_MASK_DIV_ZERO));
 tbb::task_scheduler_init tsi;
std::vector<float> foo(16);
//make FPE outside TBB
//foo[0] = std::sqrt(bar);
try {
 tbb::parallel_for(
 tbb::blocked_range<size_t>(0, foo.size()),
 [&](const tbb::blocked_range<size_t>& range) {
std::printf("beforen");
 for (auto i=range.begin(); i!=range.end(); ++i)
 {
 std::printf("%in", int(i));
 foo[i] = std::sqrt(float(i));
//make FPE inside TBB algorithm
if (i==15)
 foo[i] = std::sqrt(bar);
 }
 std::printf("aftern");
 }, tbb::auto_partitioner());
}catch (std::exception& e)
 {
 std::printf("exception: %sn", e.what());
 }
return 0;
}

5 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.
Portrait de Raf Schietekat

Is this for a Microsoft compiler on x86? Then aren't those settings only for SSE instructions, with FPU instructions still masked by default? But even if the compiler decides on SSE by default and only uses the FPU to optimise that particular case, it shouldn't generate a C++ exception, I suppose.

I've experienced that this environment will catch(...) a bus error (when dereferencing a dangling pointer or so), which is also rather strange (compared to Linux). What happens if you surround the freestanding offending instruction with a try/catch(...)? If it is caught that way, perhaps that might hint at an explanation after inspecting the source code for TBB, but it's a long shot, and others with more FP experience in this environment (or access to it for reproduction purposes) might be better able to assist.

BTW, you don't need a task_scheduler_init anymore (except for specific purposes).

Portrait de Anders W. K.

Thanks for replying.  I'm using vs2012 and 64bit mode, so no FPU.

I figured out the cause..  When I ran the program from inside VS (both with and without debugging) my program used the correct tbb.dll from the distribution of tbb that I was linking against.  But when I ran from command prompt it used whatever tbb.dll it found in the path, which happened to be and old version of tbb.  This is what was causing the exception in release mode.

Portrait de Raf Schietekat

Thanks for letting us know (I'll assume you only just found out, yourself).

Portrait de Vladimir Polin (Intel)

Anders,

Could you put [SOLVED] to the subject that people can google the answer later?

thanks,
--Vladimir 

Connectez-vous pour laisser un commentaire.