خرید بک لینک

Vote count: 0

In finding a bug which made everything tu into NaNs when ruing the optimized version of my code (compiling in g++ 4.8.2 and 4.9.3), I identified that the problem was the -Ofast option, specifically, the -ffinite-math-only flag it includes.

One part of the code involves reading floats from a FILE* using fscanf, and then replacing all NaNs with a numeric value. As could be expected, however, -ffinite-math-only kicks in, and removes these checks, thus leaving the NaNs.

In trying to solve this problem, I stumbled uppon this, which suggested adding -fno-finite-math-only as a method attribute to disable the optimization on the specific method. The following illustrates the problem and the attempted fix (which doesn't actually fix it):

#include <cstdio>
#include <cmath>

__attribute__((optimize("-fno-finite-math-only"))) 
void replaceNaN(float * arr, int size, float newValue){
    for(int i = 0; i < size; i++) if (std::isnan(arr[i])) arr[i] = newValue;
}

int main(void){
    const size_t cnt = 10;
    float val[cnt];
    for(int i = 0; i < cnt; i++) scanf("%f", val + i);
    replaceNaN(val, cnt, -1.0f);
    for(int i = 0; i < cnt; i++) printf("%f ", val[i]);
    retu 0;
}

The code does not act as desired if compiled/run using echo 1 2 3 4 5 6 7 8 nan 10 | (g++ -ffinite-math-only test.cpp -o test && ./test), specifically, it outputs a nan (which should have been replaced by a -1.0f) -- it behaves fine if the -ffinite-math-only flag is ommited. Shouldn't this work? Am I missing something with the syntax for attributes in gcc, or is this one of the afforementioned "there being some trouble with some version of GCC related to this" (from the linked SO question)

A few solutions I'm aware of, but would rather something a bit cleaner/more portable:

  • Compile the code with -fno-finite-math-only (my interrim solution): I suspect that this optimization may be rather useful in my context in the remainder of the program;
  • Manually look for the string "nan" in the input stream, and then replace the value there (the input reader is in an unrelated part of the library, yielding poor design to include this test there).
  • Assume a specific floating point architecture and make my own isNaN: I may do this, but it's a bit hackish and non-portable.
  • Prefilter the data using a separately compiled program without the -ffinite-math-only flag, and then feed that into the main program: The added complexity of maintaining two binaries and getting them to talk to each other just aren't worth it.
asked 52 secs ago

برچسب: نویسنده: استخدام کار تاريخ: شنبه 19 تير 1395 ساعت: 11:38

صفحه بندی