Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

C++ Template Question

Name: Anonymous 2012-10-07 21:47


template <size_t N>
void print_members(int (&arr)[N]) { ... }


so is C++ going to create a new function for every different sized array I use

Name: Anonymous 2012-10-07 22:05

>>1
It only has to behave ``as if'' it does. That's a quality of implementation issue!

Name: Anonymous 2012-10-07 23:00

void f(T array[N]) in C and C++ might as well be void f(T * array). There is no difference in the declaration.

So what your template will do, is to make different functions, each with the parameter N substituted as immediate values.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-08 2:16

>>2
I do not know of any current compiler that does such optimisation transformations.

Name: Anonymous 2012-10-08 3:50

>>2
the compiler could try to implement the function as:


void print_members(int* arr, int N) { ... }


it would work alright as long as the function was invoked as:


print_members<SOME_CONSTANT>(arr);


But you run into problems as soon as the programmer does:


void (*fn)(int*) = print_members<SOME_CONSTANT>;


because now you have to somehow store the SOME_CONSTANT parameter in the function pointer, which just doesn't work. So the implementation above can't always be used. Basically, every time [code]print_members<SOME_CONSTANT> is referenced but not called, it needs to point to some code that does what is described. But if you are just calling it, then you are free to call a different function with an extra hidden parameter to get the same effect.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-08 4:03

>>5

void print_members__18(int *a) { print_members(a, 18); }
void print_members__42(int *a) { print_members(a, 42); }

void (*fn)(int*) = print_members__18;


Once again, no known compiler implements this. It's essentially a form of compile-time refactoring. The "size is no concern" attitude doesn't help either. Nevertheless, it would be awesome if the compiler could turn stuff like

func(5);
func(18);
func(29);
func(62);
...
func(2);
func(8);


into


int arr[] = { 5, 18, 29, 62, ... 2, 8 };
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]);i++)
 func(arr[i]);

Name: Anonymous 2012-10-08 5:41

>>6

I just generated assembly output from g++ to confirm. It created a new function each time. I very much like the features of C++ but very disappointed to find this. I wonder how std::array made it into C++ if you can't template its size without bloating.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-08 6:54

>>7
The "size is no concern" attitude doesn't help either.

In either case you should've tried with -Os, as if they'd somehow managed to do such an optimisation, I expect it to be only under -Os. I think C++ compilers should at least enable you to view the "intermediate" C output, so you can spot such inefficiencies quickly.

Name: Anonymous 2012-10-08 8:06

>>7
Everything related to templates is bloated like fuck.
For example, std::cout << "Hello world" << std::endl; usually compiles into a 500K~ binary.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-08 8:32

>>9
500KB!? What platform is that?

Statically linked on Windows is 64KB (compare 40KB for a printf()), dynamically linked is 16KB for both, dynlink + custom link options is 2.5KB for the cout and 1.5KB for printf. Cutting out the startup code gets it down to 2KB for the cout and 1KB for the printf. .bss stripping turns the printf one into 636 bytes (mostly header bloat), and 1547 for cout which is still 2.5x bigger. Why MS didn't default to settings which produce the last two sizes is anyone's guess...

Name: Anonymous 2012-10-08 9:14

>>8

I used g++ -std=c++11 -O3 -S

Name: Anonymous 2012-10-08 11:16

>>10

500KB executables are mostly product of a compiler statically linking everything that can or can't be linked.

Name: Anonymous 2012-10-08 11:21

Everyone knows what sort of hell comes with dynamic linking.

Name: Anonymous 2012-10-08 11:59

>>5
vtables
Look them up.

Name: Anonymous 2012-10-08 13:10

>>4
>>6
>>8
>>10
Shalom, hymie!

Name: Anonymous 2012-10-08 13:34

>>6
I think it's more interesting to look at the generated assembly code. The problem being that loading an immediate takes 1 cycle on most (if not all) architectures and loading from memory can take 300 cycles, making the condensed code extremely slow should it decide to use RAM to store this data. It also means that cache will have to be updated, pushing data that actually needs to be in RAM out.

That said, I don't think that optimization would come into play all that often.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-09 1:39

>>16
Having compact data in the cache is better than "loose" code in there, especially if that long line of code is big enough to make a loop fall out of the cache. A plain call+push imm8 is 7 bytes; even if you stored that array as 4-byte ints (thus wasting 3/4 of the space in that example) you're still getting an improvement: 7n vs 4n + loop code overhead. Store as single bytes and you get even better density, it's now 7n vs 1n + overhead.

"instructions" and "data" are the same to the memory, don't think instruction fetches are free.

Name: Anonymous 2012-10-09 2:00

>>17
You're implying it's on x86. 5-byte calls is an x86 flaw.

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-10 1:50

>>18
Name an architecture where you can make a call to anywhere in a 32-bit address space and pass one 32-bit parameter in less than 7 bytes

Name: Anonymous 2012-10-10 2:19

>>19
callg arglist.ab, dst.ab

Name: Anonymous 2012-10-10 3:17

>>17
Why did you change your tripcode, FrozenVoid?

Name: Cudder !MhMRSATORI!fR8duoqGZdD/iE5 2012-10-10 3:48

>>20
1 byte for opcode
1 byte for arglist operand type
4 bytes for arglist pointer
1 byte for destination address operand type
4 bytes for destination address

11 + 4 bytes for the actual parameter. Nice try, not good enough.

Name: Anonymous 2012-10-10 5:29

>>19
Simple, just define an architecture with a hardware implementation of the FrozenVoid infinite compression algorithm.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List