[SOLVED] TBB and floating point exceptions

[SOLVED] TBB and floating point exceptions

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 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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).

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.

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

Anders,

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

thanks,
--Vladimir 

Leave a Comment

Please sign in to add a comment. Not a member? Join today