For the past approx. 20 years I've been working on a program for 3D graphics that implements a METAFONT-like language. It's in C++. I now have started working on a format and functions for writing the data for the 3D objects to a binary file and then reading them in again. It is intended for saving and fast-loading data that has been calculated in order to avoid calculating it again each time the program is run.
The syntax for the file format is intended to be for a machine-like language that allows for the highest possible efficiency without having to worry about being comfortable for people to read or write.
My question relates to the way data is read into registers: The architecture of my computer is x86_64, so obviously I have 64-bit registers. Does it pay at all to read data into objects smaller than 64 bit, i.e., chars, ints or floats? Isn't anything that's read read into a 64-bit register? As I understand it, any unused bits of a register are set to 0, which is an extra step, so less efficient than just reading a long int or a double in the first place. Is this correct and does anyone have any suggestion on how I should proceed?
This is what I tried in response to Scheff's Cat's comment.
/* ttemp.c */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void
write_uint(unsigned int i);
void
write_ulong(unsigned long int li);
int fd = 0;
int
main(int argc, char *argv[])
{
printf("Entering ttemp.\n");
fd = open("ttemp.output", O_WRONLY | O_CREAT, S_IRWXU);
printf("fd == %d\n", fd);
write_uint(~0U);
write_ulong(~0UL);
close(fd);
printf("Exiting ttemp.\n");
return 0;
}
void
write_uint(unsigned int i)
{
write(fd, &i, 4);
return;
}
void
write_ulong(unsigned long int li)
{
write(fd, &li, 8);
return;
}
Then I ran:
gcc -pg -o ttemp ttemp.c
ttemp
gprof ttemp
This is the contents of ttemp.output, according to Emacs in Hexl mode, so the objects were obviously written to the output file:
00000000: ffff ffff ffff ffff ffff ffff ............
This was the relevant portion of the output of gprof:
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) no time propagated
index % time self children called name
0.00 0.00 1/1 main [8]
[1] 0.0 0.00 0.00 1 write_uint [1]
-----------------------------------------------
0.00 0.00 1/1 main [8]
[2] 0.0 0.00 0.00 1 write_ulong [2]
-----------------------------------------------
So, not very illuminating. My guess is that the nulling in the registers is performed at the level of the processor and any time it takes won't show up on the system call level. However, I'm not a systems programmer and my grasp of these topics isn't particularly firm.