Write a benchmark (part 2)

Back in the src/exercises directory:

Switch to benchmark.h

In preparation of further simplifications, let’s also switch to the "benchmark.h" header, which defines a few helper functions and already implements main().

Your peakflop.cpp should look like this now:

#include "benchmark.h"

void peak(benchmark::State &state)
{
  float x = 1;
  benchmark::DoNotOptimize(x)
  for (auto _ : state) {
    x = x * 3 + 1;
  }
  benchmark::DoNotOptimize(x)

  // compute FLOP/s and FLOP/cycle
  add_flop_counters(state, 2);
}

// Register the function as a benchmark
BENCHMARK(peak);

Where’s the performance?

On an Intel CPU you will likely see 0.5 FLOP/cycle now. That’s quite far away from the 4 FLOP/cycle my slides showed for scalars. Where’s the factor of 8 hiding?

TIP

addss and mulss require more than 1 clock cycle to produce a result; rather on the order of 3–5 cycles.

:green_book: uops.info on mulss (Lat: Latency — the time it takes from start of instruction execution until the result is ready. TP: Throughput — the time it takes before another instruction can be executed. time = clock cycles. TP 0.5 means the CPU can execute two of these instructions per clock cycle.)

Issue independent instructions

Edit peak to issue more independent addss and mulss instructions per loop iteration.

Remaining factor of 2?

You should be able to reach 2 FLOP/cycle now. What is the remaining factor of 2?

TIP

:green_book: uops.info on vfmadd132ss

Why no FMA?

Our example computes a multiplication with subsequent addition. So why doesn’t the compiler emit a fused multiply-add (FMA) instruction?

TIP

:green_book: GCC x86 Options

:green_book: GCC Optimize Options: -ffp-contract

Note the defaults. -ffp-contract defaults to producing FMAs already. However, the compiler assumes your code should be able to run on the original x86_64 AMD Athlon CPU. That CPU didn’t have FMA instructions.

Compile with -march=native

Use ccmake to set CMAKE_CXX_FLAGS to -march=native.

ninja -v run_peakflop

Outlook

We will come back to this benchmark after we covered vectorization and std::simd.

results matching ""

    No results matching ""