Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would you combine two 32 bit integers into a 64 bit integer?

Tags:

c++

c

Recently I saw how a compiler combined two 32 bit integers which were values of properties of a class and stored them as a 64 bit integer. My question now is, why is this done? What advantages are there when combining integers?

for example if we had the following properties of a class

class FooBar {
 int x = 1;
 int y = 100;
}

so instead of

i32 = 00000001
i32 = 01100100

We get:

i64 = 0000000101100100

Why would you combine them?

like image 236
Asperger Avatar asked Apr 22 '17 17:04

Asperger


2 Answers

The existing (as I write this) answer and comments, while partially correct, miss the point of this optimization. It is to replace two instructions (working with 32-bit data) with one instruction (working with 64-bit data). This results in a very slight reduction in code size and probably execution time.

The compiler is initializing both variables with one 64-bit instruction (since they share consecutive memory addresses). The variables are separate, and will be accessed separately. No shifting or masking is needed.

This is frequently seen in constructors when many members are initialized. A frequent case is with zero initialization, where the compiler will zero out a register then use that one value to initialize multiple members, combining writes to consecutive memory addresses with a larger single write (for example, by writing a 16-bit short zero value instead of two 8-bit ones).

like image 87
1201ProgramAlarm Avatar answered Oct 04 '22 09:10

1201ProgramAlarm


I believe you're observing an optimization. Intel instructions such as PADDSW assume multiple packed operands.

https://en.wikipedia.org/wiki/X86_instruction_listings

There are also benefits in only using 1 entry in a 64bit architecture cache.

There is a cost to unpack if you only want one of the values, but I suspect whatever code optimizer is running estimates there are better savings pack the values.

It used to be normal to align all members of a C struct onto a word boundary. That is a single char and an int would not be packed, but aligned to the word size of the machine. So, struct { char, int} would have a sizeof(..) of 8 bytes. I'm guessing that situation flipped?

Very interesting.

like image 34
Sam Avatar answered Oct 04 '22 09:10

Sam