Snippets

Nathanaël Schaeffer demonstrate the incompatibility of floating-point exceptions with SIMD optimizations

Updated by Nathanaël Schaeffer

File test_fpexcept.c Modified

  • Ignore whitespace
  • Hide word diff
 
 
 #define N 1000
-double l[N];
-double l_2[N];
+int l[N];
+float l_2[N];
 
-void init(double* x, int n)
+void init(int* x, int n)
 {
 	for (int i=0; i<n; i++)  x[i] = i*(i+1);
 	x[100] = 0;	// add some zeros at random places
 	// This loop can be vectorized when compiled with -fno-trapping-math
 	for (int i=0; i<N; i++) {
 		int ii = l[i];
-		l_2[i] = (ii==0) ? 0.0 : 1.0/ii;            // avoid division by 0 !
+		l_2[i] = (ii==0) ? 0.0f : 1.0f/ii;            // avoid division by 0 !
 	}
 
 	printf("%g %g\n", l_2[30], l_2[100]);		// do something with data to avoid eliminating all code.
Updated by Nathanaël Schaeffer

File test_fpexcept.c Modified

  • Ignore whitespace
  • Hide word diff
 
 void init(double* x, int n)
 {
-	for (int i=0; i<n; i++)  l[i] = i*(i+1);
-	l[100] = 0;	// add some zeros at random places
-	l[30] = 0;
+	for (int i=0; i<n; i++)  x[i] = i*(i+1);
+	x[100] = 0;	// add some zeros at random places
+	x[30] = 0;
 }
 
 
Created by Nathanaël Schaeffer

File test_fpexcept.c Added

  • Ignore whitespace
  • Hide word diff
+/* TESTED WITH GCC 12.2.0
+* 1) By default the compiler assumes exceptions can occur. Compile with:
+* 	gcc -O3 -lm test_fpexcept.c
+* run ./a.out prints "0 0"
+* 
+* 2) Now tell the compiler no exceptions will occur, to enable further optimizations. Compile with:
+*     gcc -O3 -fno-trapping-math -lm test_fpexcept.c
+* run ./a.out generates a spurious exception.
+*/
+
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <fenv.h>
+
+
+#define N 1000
+double l[N];
+double l_2[N];
+
+void init(double* x, int n)
+{
+	for (int i=0; i<n; i++)  l[i] = i*(i+1);
+	l[100] = 0;	// add some zeros at random places
+	l[30] = 0;
+}
+
+
+int main()
+{
+	init(l,N);
+
+	// -fno-trapping-math basically tells the compiler (among other things) we will NOT call the following line:
+	feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);                // turn this on to track NaNs or other floating-point exceptions (requires gcc, #define _GNU_SOURCE and #include <fenv.h>)
+
+	// This loop can be vectorized when compiled with -fno-trapping-math
+	for (int i=0; i<N; i++) {
+		int ii = l[i];
+		l_2[i] = (ii==0) ? 0.0 : 1.0/ii;            // avoid division by 0 !
+	}
+
+	printf("%g %g\n", l_2[30], l_2[100]);		// do something with data to avoid eliminating all code.
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.