1

I'm working with a function on the critical path. The code looks like so:

void ProcessData(const byte* input, size_t size)
{
    ALIGN_ARRAY(16) int32_t m0[2] = { ((const int32_t*)input)[0] };
    ALIGN_ARRAY(16) int32_t m1[2] = { ((const int32_t*)input)[1] };
    ...
}

The first element, m0[0] is the one I care about. The second element, m0[1] is scratch space and keeps things aligned before m is shipped off to the SIMD engine. m0[1] will be populated with a value, but I don't need it initialized.

This code is called repeatedly and very influential on benchmarking results, so its important to minimize everything. I want the compiler to know it can initialize the first element because the code may be better optimized.

How do I ensure only the first element is initialized, and the remaining elements in the array are uninitialized? Is it even possible?


This question is opposite of questions like Initialization of a normal array with one default value, Static array initialization of individual elements in C++ and Array initialization with {0}, {0,}?

I'm also aware that initialization is different than assignment; and some of the details of zero-, default- and value-initialization and how PODs affect it.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • 2
    You either initialize nothing or everything. In your case, leave the array uninitialized and then assign to its first element. – Kerrek SB May 07 '16 at 11:25
  • Thanks @KerrekSB. I was kind of afraid of that. If that's the case, then you may as well answer for the record. – jww May 07 '16 at 11:29

2 Answers2

1

Not sure what is input especially as it has type of byte and you are casting to int32. If you are on x86 platform watch out for backwords (endianness issues).

Try something like this but with the appropriate cast.

void ProcessData(const byte* input, size_t size)
{
    ALIGN_ARRAY(16) int32_t m0[2];
    m0[0]= = (const int32_t*)input)[0];
    ALIGN_ARRAY(16) int32_t m1[2];
    m1[0] = (const int32_t*)input)[1];
    ...
}
T33C
  • 4,341
  • 2
  • 20
  • 42
1

With a stack-allocated array it's impossible. Even in C++03, any omitted elements from the initializer list are default-initialized (if class type) or value-initialized (if not). You have a couple of options:

  1. Leave array uninitialized, initialize one element.
  2. Use a class wrapper.
  3. Overengineer the scenario.

Here's how you might do that.

const uint8_t input[...];

std::pair< int32_t*, std::ptrdiff_t > ms[...];

for (int i = 0; i < ...; ++i)
{
    ms[i] = std::get_temporary_buffer<int32_t>(2);
    std::copy((const int32_t*)input + i, (const int32_t*)input + i + 1,
              std::raw_storage_iterator<int32_t*, int32_t>(ms[i].first));
}
// later loop std::return_temporary_buffer(ms[...].first); at end of function