enabled by setting the variable <tt>CMAKE_CXX_FLAGS</tt> to
<tt>"-march=native"</tt> in the cmake build settings (on the command line,
specify <tt>-DCMAKE_CXX_FLAGS="-march=native"</tt>, see the deal.II README for
-more information). Similar options exist for other compilers.
+more information). Similar options exist for other compilers. We output
+the current vectorization length in the run() function of this example.
<h3>Running multigrid on large-scale parallel computers</h3>
When we run this program in 2D for quadratic ($Q_2$) elements, we get the
following output (when run on one core in release mode):
@code
+Vectorization over 2 doubles = 128 bits (SSE2), VECTORIZATION_LEVEL=1
Cycle 0
Number of degrees of freedom: 81
Total setup time (wall) 0.00159788s
approximately eight times as many degrees of freedom with each cycle:
@code
+Vectorization over 2 doubles = 128 bits (SSE2), VECTORIZATION_LEVEL=1
Cycle 0
Number of degrees of freedom: 125
Total setup time (wall) 0.00231099s
following program output:
@code
+Vectorization over 2 doubles = 128 bits (SSE2), VECTORIZATION_LEVEL=1
Cycle 0
Number of degrees of freedom: 729
Total setup time (wall) 0.00633097s
another round of mesh refinement in the lower order methods:
@code
+Vectorization over 2 doubles = 128 bits (SSE2), VECTORIZATION_LEVEL=1
Cycle 0
Number of degrees of freedom: 4913
Total setup time (wall) 0.0842004s
// The function that runs the program is very similar to the one in
// step-16. We do few refinement steps in 3D compared to 2D, but that's
// it.
+ //
+ // Before we run the program, we output some information about the detected
+ // vectorization level as discussed in the introduction.
template <int dim>
void LaplaceProblem<dim>::run ()
{
+ {
+ const unsigned int n_vect_doubles = VectorizedArray<double>::n_array_elements;
+ const unsigned int n_vect_bits = 8*sizeof(double)*n_vect_doubles;
+
+ pcout << "Vectorization over " << n_vect_doubles
+ << " doubles = " << n_vect_bits << " bits ("
+ << Utilities::System::get_current_vectorization_level()
+ << "), VECTORIZATION_LEVEL=" << DEAL_II_COMPILER_VECTORIZATION_LEVEL << std::endl;
+ }
+
for (unsigned int cycle=0; cycle<9-dim; ++cycle)
{
pcout << "Cycle " << cycle << std::endl;
*/
double get_cpu_load ();
+ /**
+ * Return the current level of vectorization as described by DEAL_II_COMPILER_VECTORIZATION_LEVEL
+ * in vectorization.h as a string. The list of possible return values is:
+ *
+ * <table>
+ * <tr>
+ * <td><tt>VECTORIZATION_LEVEL</tt></td>
+ * <td>Return Value</td>
+ * <td>Width in bits</td>
+ * </tr>
+ * <tr>
+ * <td>0</td>
+ * <td>disabled</td>
+ * <td>64</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>SSE2</td>
+ * <td>128</td>
+ * </tr>
+ * <tr>
+ * <td>2</td>
+ * <td>AVX</td>
+ * <td>256</td>
+ * </tr>
+ * <tr>
+ * <td>3</td>
+ * <td>AVX512</td>
+ * <td>512</td>
+ * </tr>
+ * </table>
+ */
+ const std::string get_current_vectorization_level();
+
/**
* Structure that hold information about memory usage in kB. Used by
* get_memory_stats(). See man 5 proc entry /status for details.
#endif
+ const std::string
+ get_current_vectorization_level()
+ {
+ switch (DEAL_II_COMPILER_VECTORIZATION_LEVEL)
+ {
+ case 0:
+ return "disabled";
+ case 1:
+ return "SSE2";
+ case 2:
+ return "AVX";
+ case 3:
+ return "AVX512";
+ default:
+ AssertThrow(false, ExcInternalError("Invalid DEAL_II_COMPILER_VECTORIZATION_LEVEL."));
+ return "ERROR";
+ }
+ }
void get_memory_stats (MemoryStats &stats)