Skip to content

Instantly share code, notes, and snippets.

@iwillspeak
Created April 30, 2013 20:42
Show Gist options
  • Save iwillspeak/5491786 to your computer and use it in GitHub Desktop.
Save iwillspeak/5491786 to your computer and use it in GitHub Desktop.
Comparison of the speed of accessing various C structures The timer code is from bitbucket.org/iwillspeak/moonbase
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include "timer.h"
struct aligned {
uint32_t o:8;
uint32_t d:8;
uint32_t s1:8;
uint32_t s2:8;
};
typedef struct aligned aligned_t;
static_assert(sizeof(aligned_t) == 4, opcode should be four bytes);
void test_aligned_bitfield(const int iterations)
{
aligned_t thing = {0};
for (int i = 0; i < iterations; ++i) {
thing.o++;
thing.d++;
thing.s1++;
thing.s2++;
}
}
struct unaligned {
uint32_t o:6;
uint32_t d:5;
uint32_t s1:5;
uint32_t s2:5;
uint32_t padding:11;
};
typedef struct unaligned unaligned_t;
void test_unaligned_bitfield(const int iterations)
{
unaligned_t thing = {0};
for (int i = 0; i < iterations; ++i) {
thing.o++;
thing.d++;
thing.s1++;
thing.s2++;
}
}
void test_array(const int iterations)
{
uint8_t thing[4] = {0};
for (int i = 0; i < iterations; ++i) {
thing[0]++;
thing[1]++;
thing[2]++;
thing[3]++;
}
}
struct bytestruct {
uint8_t o, d, s1, s2;
};
typedef struct bytestruct bytestruct_t;
void test_struct(const int iterations)
{
bytestruct_t thing;
for (int i = 0; i < iterations; ++i) {
thing.o++;
thing.d++;
thing.s1++;
thing.s2++;
}
}
int main(int argc, char* argv[])
{
static const int iterations = 100000;
Timer* timer;
uintmax_t aligned, unaligned, array, struc;
timer = timerCreate();
test_aligned_bitfield(iterations);
aligned = timerGetMicrosecondDelta(timer);
test_unaligned_bitfield(iterations);
unaligned = timerGetMicrosecondDelta(timer);
test_array(iterations);
array = timerGetMicrosecondDelta(timer);
test_struct(iterations);
struc = timerGetMicrosecondDelta(timer);
free(timer);
printf("a\tu\tc\ts\n");
printf("%zu\t%zu\t%zu\t%zu\n", sizeof(aligned_t), sizeof(unaligned_t),
sizeof(uint8_t) * 4, sizeof(bytestruct_t));
printf("%"PRIuMAX"\t%"PRIuMAX"\t%"PRIuMAX"\t%"PRIuMAX"\n",
aligned, unaligned, array, struc);
exit(EXIT_SUCCESS);
}
#include "timer.h"
#include <stdlib.h>
#include <stdio.h>
Timer* timerCreate(void) {
Timer* t = calloc(1, sizeof(Timer));
timerReset(t);
return t;
}
void timerReset(Timer* timer) {
#ifdef __MACH__
gettimeofday(&timer->zero, NULL);
#else
clock_gettime(CLOCK_MONOTONIC, &timer->zero);
#endif
}
unsigned long timerGetMicroseconds(Timer* timer) {
#ifdef __MACH__
struct timeval now;
gettimeofday(&now, NULL);
return (now.tv_sec-timer->zero.tv_sec)*1000000+(now.tv_usec-timer->zero.tv_usec);
#else
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (now.tv_sec-timer->zero.tv_sec)*1000000+(now.tv_nsec-timer->zero.tv_nsec)/1000 ;
#endif
}
unsigned long timerGetMicrosecondDelta(Timer* timer) {
unsigned long delta;
delta = timerGetMicroseconds(timer);
timerReset(timer);
return delta;
}
#ifndef __TIMER_HEADER__
#define __TIMER_HEADER__
#ifdef __MACH__
#include <sys/time.h>
#else
#include <time.h>
#endif
typedef struct Timer_s {
#ifdef __MACH__
struct timeval zero;
#else
struct timespec zero;
#endif
} Timer;
#define smooth(value, delta) (((float)(value)/(float)1000000) * (float)(delta))
/**
* Reset the timer
*
* Delta time values measured will be from the calling of this
* method.
*
* @param timer to reset
*/
void timerReset(Timer* timer);
/**
* Creates a new timer
*
* @return timer pointer
*/
Timer* timerCreate(void);
/**
* Return the number of microseconds since the timer was reset
*
* The amount of time since the timer was reset or the last delta was
* read is returned.
*
* @param timer to read
* @return time since reset in microseconds
*/
unsigned long timerGetMicroseconds(Timer* timer);
/**
* Gets the delta and resets a timer
*
* The amount of time since the timer was reset or the last delta was
* read is returned and the timer is reset.
*
* @param timer to read
* @return delata in microseconds
*/
unsigned long timerGetMicrosecondDelta(Timer* timer);
#endif
@iwillspeak
Copy link
Author

This is the result of compiling and running the above three files on OS X 10.8 with Clang:

a   u   c   s
4   4   4   4
1358    1372    238 238

And with gcc:

a   u   c   s
4   4   4   4
1995    873 325 324

I am interested in the relative speeds on various other platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment