3

This is from memory, so I could be misusing a few words, but the meaning should be understandable

I'm currently at University, doing a BIT majoring in programming - We started C++, and when we started using arrays, our C++ teacher (a teacher with strange ideas and programming rules, such as no comments whatsoever allowed) told us that we should make our array sizes in multiples of 4 to be more efficient:

char exampleArrayChar[ 4 ]; //Allowed
float exampleArrayChar[ 6 ]; //NOT Allowed
int exampleArrayChar[ 8 ]; //Allowed

He said the reason behind this was because of the way the computer does its memory allocation.

The computer allocated the memory address / locations for each array element in groups of four bytes - so a 8 element array was done in 2 memory groups.

So the issue was that if you made an array of size 6, it would assign 2 groups of 4, but then mark 2 of those bytes (out of the 8) as invalid / void, rendering them unusable until the whole array was released from memory.

While this to me sounds plausible in regard to other computer math (such as 1gb = 1024mb instead of exactly 1000) I am interested in knowing:

  • Just how true this is, and what the gain would be, if any, by doing this
  • Is this just C++? (I would assume not, but still worth asking)
  • Just some more info on this all round - for example, why 4? Isn't computer math normally binary, and thus 2's?

Looking around on the web I've been unable to find anything of major use or relevance.

Gareth Jones
  • 1,241
  • 4
  • 17
  • 38
  • 4
    Yeah, I'll call BS on this one. There's nothing that says that you must allocate in multiples of 4. – Dennis Meng Aug 17 '13 at 01:25
  • 7
    Drop the class and find a better professor. – NG. Aug 17 '13 at 01:25
  • You've misunderstood the teacher or she's wrong. I think she's talking about data alignment, not the size – a.lasram Aug 17 '13 at 01:26
  • @a.lasram Why "she"? The OP refers to the prof as a "he" – Dennis Meng Aug 17 '13 at 01:26
  • Its a He, and he's not saying you HAVE to - just that its more efficient. I can see that I said must in the question - ill update that. and yes this teacher is not that great - he has the dumbest rules that go against most programming standards – Gareth Jones Aug 17 '13 at 01:27
  • Even more wood behind @SB 's suggestion-arrow. – WhozCraig Aug 17 '13 at 01:28
  • Another C++ HE teacher. Anyway, he's not that good at explaining things. It's not more efficient to have multiple 4 size – a.lasram Aug 17 '13 at 01:31
  • 1
    Is your teacher the kind who *welcomes* argument from his students, or *punishes* it? The tendency to punish correlates strongly with being a moron, which also correlates strongly with teaching crackpot ideas, so watch your step. – Beta Aug 17 '13 at 01:33
  • 1
    Following that logic it is clear that `int meaningfulName;` is not allowed either. `int unrelatedData[4];` would probably be the way to go then. – IInspectable Aug 17 '13 at 01:34
  • hehe, yes - As most people have commented on, hes the standard "those who can do, those who can't teach" teacher. The main reason I'm asking the question is because he said he would remove marks if we didn't do it this way (hence punish), so I am interested in finding out any truth to his statement – Gareth Jones Aug 17 '13 at 01:35
  • @IInspectable `int meaningfulName` is ok since `char exampleArrayChar[4]` is allowed. how about `char meaningfulName` – a.lasram Aug 17 '13 at 01:37
  • 2
    You should make the array as big as you need as first consideration. Let the compiler worry about optimizations. – Neil Kirk Aug 17 '13 at 01:54

4 Answers4

8
float exampleArrayChar[ 6 ]; //NOT Allowed

Considering that float is 4 bytes (almost universally, due to the widespread adoption of IEEE-754 encoding for floating-point numbers), any number of floats is already going to be a multiple of four bytes. Your example would be 24, and not problematic. On x86 (and x64), SSE instructions really prefer data to be 8 byte aligned... again having a float array of size 6 elements = 24 bytes won't interfere with this.

The only larger multiple that really matters for alignment is the size of the cache line, which varies widely with implementation (code compiled for x86 may find itself running on CPUs with 32 byte, 128 byte, or other cache sizes, all from the same machine code). And yes cache alignment can make a big performance difference, but alignment to cache lines is not necessarily better, in fact it is often much worse to be aligned because it evokes collisions on cache mapping which are similar to false sharing as far as the performance hit is concerned.

See What is "cache-friendly" code? and Why is my program slow when looping over exactly 8192 elements? and other questions linked from those.

But as soon as your professor got to No comments whatsoever allowed you should be in the Dean's office demanding a refund of your tuition.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
3

Assuming your teacher really told you what you are saying above, your teacher would be wrong (which wouldn't surprise me at all). What is true, however, is that when you allocate memory from the heap, the memory chunks being allocate are probably a multiple of some power of 2 because memory would end up getting fragmented in unfortunate ways otherwise, at least, when using a general purpose memory allocator. Thus, you may be wasting a couple of bytes. I wouldn't bother with these details, however, unless you have many object: get the program right first using the semantically correct approach.

The best way to deal with these issues, however, is not to use arrays in the first place but rather to use std::vector<T> or std::deque<T>.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

That teacher has some really funky (and wrong ideas). To explain why stuff is let's check each statement.

... our C++ teacher ... told us that we should make our array sizes in multiples of 4 to be more efficient... He said the reason behind this was because of the way the computer allocated memory spaces (spaces might not be the correct work - basicly the memory address for each element in the array)

C (and C++) grant that if you allocate memory, regardless of type, it will be there, otherwise a runtime error occurs. What he might have said is that it would be a good practice (it isn't) to allocate more space to, say, accommodate some overflow error. However C and C++ grant that all memory in a static (by this I mean not declared dynamically through new(), although I'm not sure about this one) array is contiguous. When declaring something, use only the amount of memory (resources) that you thing will need to use.

The computer allocated the memory address / locations for each array element in groups of four - so a 8 element array was done in 2 memory groups (again, groups isn't the correct word)

An int is at least 4 bytes, this being the only sentence where it would make sense to hear the before quote. Since you can refer to any byte in memory through a reference, there isn't a explicit need to divide memory in groups of four, unless some environmental issue arises.

While this to me sounds plausible in regard to other computer math (such as 1gb = 1024mb instead of exactly 1000)...

Although this is best discussed in other places, GB and GiB are separate things; look it on Wikipedia. However, and when regarding memory, there's an informal convention that the Byte unit has its' multiples ordered on 210, 220, 230 and so forth.

Finally, as the previous commenter said, the Right Way To Do Things in C++ is through the new container classes, being std::vector<T> the most array-like container. Leave this kind of array declarations for something really simple or for legacy C code.

Doktoro Reichard
  • 577
  • 1
  • 7
  • 22
1

Recently while I was probing down Superuser I came across a post describing fragmentation, that lead me to this post on Wikipedia. Quoting:

For example, memory can only be provided to programs in chunks divisible by 4, 8 or 16, and as a result if a program requests perhaps 23 bytes, it will actually get a chunk of 24. When this happens, the excess memory goes to waste. In this scenario, the unusable memory is contained within an allocated region, and is thus termed internal fragmentation.

Still, and as most people pointed out, the amount of space "saved" isn't that big a deal, since in most modern systems there exists a lot of memory (GB's); it is better to design according to the needs of the program, not to the needs of the machine.

Doktoro Reichard
  • 577
  • 1
  • 7
  • 22