Shredderroy
Shredderroy

Reputation: 2920

Allocating 32-bit integer arrays in 64-bit machines

I have a 64-bit i7 machine. Suppose I allocate memory for n 32-bit integers. How many physical registers will actually be used in the allocation: n, or n/2?

I tried to write the following simple programme to find out.

#include <iostream>
#include <cstdlib>

using namespace std;

int main (int argc, char *argv[]) {
    int a[4];
    cout << &a[0] << "\t" << &a[3] << endl;
    cin.ignore (1);
    return 0;
} // End main ()

The output is:

0018FA04        0018FA10

They seem further apart than they should be. Why aren't the addresses 04 and 07? And does this mean that the system is actually allocating four (or more) integers, instead of packing the four 32-bit integers into two 64-bit registers?

Thanks in advance for your help.

Upvotes: 1

Views: 1716

Answers (4)

Andrew Tomazos
Andrew Tomazos

Reputation: 68588

I have a 64-bit i7 machine. Suppose I allocate memory for n 32-bit integers. How many physical registers will actually be used in the allocation: n, or n/2?

A 64-bit i7 machine is a x86_64 architecture.

On this architecture an array of 32-bit integers will be allocated fully-packed, meaning the size of the array will be 4n bytes.

If by physical registers you mean machine words, and you consider a machine word to be 64-bit on x86_64, than yes it will use n/2 machine words.

I wouldn't use the word physical registers, this can be confused with cpu registers, which is not where an array (unless very small and optimizer is aggressive) is allocated.

They seem further apart than they should be. Why aren't the addresses 04 and 07? And does this mean that the system is actually allocating four (or more) integers, instead of packing the four 32-bit integers into two 64-bit registers?

Because the architecture is byte-addressed not word-addressed. They are 12 bytes apart as expected.

Upvotes: 2

ShinTakezou
ShinTakezou

Reputation: 9661

First, use sizeof(int) to know how wide is int on your system. Then sizeof(int) * N should give the number of char your array occupy. Unless there exists what I would call strange systems (because of strange alignment or padding on data which I would consider already aligned... edit though 64bit systems may prefer to align 32bit data padding them with extra 32bit, and it sounds almost logical) it should be that sizeof(int) * 4 == sizeof(a) in the specific example provided. Of course, likely the array a is not kept into any CPU register, but it is on the stack of the main function.

edit

For example,

#include <iostream>
#include <cstdlib>

using namespace std;

int main (int argc, char *argv[]) {
    int a[4];
    cout << &a[0] << "\t" << &a[3] << endl;
    cout << sizeof(int) << " " << sizeof(a) << endl;
    cin.ignore (1);
    return 0;
} // End main ()

on a sparc machine, compiled with Sun CC -m64, gave

ffffffff7ffff748        ffffffff7ffff754
4 16

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490048

Each int is 32 bits (4 bytes). 3 of those make 12 bytes. 0x0018FA10 - 0x0018FA04 = 12.

Upvotes: 9

egrunin
egrunin

Reputation: 25053

This is the layout:

a[0]; // 0018FA04 00 00 00 00
a[1]; // 0018FA08 00 00 00 00
a[2]; // 0018FA0C 00 00 00 00
a[3]; // 0018FA10 00 00 00 00

It has nothing to do with register size.

Upvotes: 2

Related Questions