2

I am running google benchmark for some basic cache testing and I get the following error:

terminate called after throwing an instance of 'std::length_error'

what():  cannot create std::vector larger than max_size()

However, I am printing the max_size and the actual size (see below) and while the max_size equals 2^60-1 it breaks at 2^28. What am I missing?

The benchmark code is below. The code is compiled using Clang 11 with c++20.

static void bm_std_vector_in_cache_double(benchmark::State& state)
{
  auto constexpr d{3.1415};

  auto const bytes = (2 << state.range(0)) * 1024;
  auto data = std::vector<double>(bytes / sizeof(double), d);
  std::cout << data.max_size() << '\n';
  std::cout << data.size() << '\n';
  for (auto _ : state){
      auto sum = 0.0;
      for(auto j = 0; j < data.size(); ++j)
        benchmark::DoNotOptimize(sum += data[j] * data[j]);
    }

  state.SetBytesProcessed(state.iterations() * data.size());
}

BENCHMARK(bm_std_vector_in_cache_double)->DenseRange(1, 20);
cigien
  • 57,834
  • 11
  • 73
  • 112
Mike
  • 3,775
  • 8
  • 39
  • 79
  • does break at `2^28` or is that the last size for which it works? Better print `max_` and requested size before you attempt to create the vector so you can see more easily where is goes off – 463035818_is_not_an_ai Nov 26 '20 at 18:56
  • 2^27 is the last size that works. – Mike Nov 26 '20 at 18:58
  • 3
    That error message is pretty badly chosen. The failure is happening because you can't allocate a contiguous block at 2^28 elements or more. But the usefulness (more accurately, the lack thereof) of `max_size` itself is arguable. [See this answer](https://stackoverflow.com/questions/9867206/practical-use-of-vectormax-size) – WhozCraig Nov 26 '20 at 19:05
  • Did you expect to achieve `2^60-1`? – n. m. could be an AI Nov 26 '20 at 19:08
  • @WhozCraig Shouldn't that throw `std::bad_alloc` instead of `std::length_error`? – Yksisarvinen Nov 26 '20 at 19:13
  • 1
    @Yksisarvinen You would think. Like I said, that's a terrible message. – WhozCraig Nov 26 '20 at 19:13
  • 2
    `auto const bytes = (2 << state.range(0)) * 1024;` What is the type of this? (yeah almost always auto). – n. m. could be an AI Nov 26 '20 at 19:26
  • bingo! The AAA got me here. auto const bytes is of type const int. auto const bytes = .... 1024L; creates a long allows for longer vectors. – Mike Nov 26 '20 at 19:49

1 Answers1

1

The issue here was that the type of bytes was an int.

auto const bytes = (2 << state.range(0)) * 1024;

changing to

auto const bytes = (2 << state.range(0)) * 1024L;

changes it to a long allowing for longer vectors and even better better unsigned long long:

auto const bytes = (2 << state.range(0)) * 1024ULL;
Mike
  • 3,775
  • 8
  • 39
  • 79