memcpy1.c
text/x-csrc
Filename: memcpy1.c
Type: text/x-csrc
Part: 0
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <immintrin.h>
/* Closer approximation of ScanKeyData - has function pointer and Datum */
typedef void (*RegProcedure)(void);
typedef uintptr_t Datum;
typedef struct ScanKeyData
{
int sk_flags;
int sk_attno;
RegProcedure sk_func;
Datum sk_argument;
} ScanKeyData;
/* */
const ScanKeyData * version1(int n, const ScanKeyData * key)
{
ScanKeyData *idxkey = (ScanKeyData *) malloc(n * sizeof(ScanKeyData));
memcpy(&idxkey, &key, n * sizeof(ScanKeyData));
for (int i = 0; i < n; i++)
{
idxkey[i].sk_attno = i + 1;
}
return idxkey;
}
/* */
const ScanKeyData * version2(int n, const ScanKeyData *key)
{
ScanKeyData *idxkey = (ScanKeyData *) malloc(n * sizeof(ScanKeyData));
for (int i = 0; i < n; i++)
{
memcpy(&idxkey[i], &key[i], sizeof(ScanKeyData));
idxkey[i].sk_attno = i + 1;
}
return idxkey;
}
#define NANOSEC_PER_SEC 1000000000
// Returns difference in nanoseconds
int64_t
get_clock_diff(struct timespec *t1, struct timespec *t2)
{
int64_t nanosec = (t1->tv_sec - t2->tv_sec) * NANOSEC_PER_SEC;
nanosec += (t1->tv_nsec - t2->tv_nsec);
return nanosec;
}
//#define NKEYS 10000000 version2 does not finish
#define NKEYS 4
#define LOOPS 10000000
void test1(int n)
{
ScanKeyData *keys;
ScanKeyData *idx;
keys = (ScanKeyData *) malloc(NKEYS * sizeof(ScanKeyData));
memset(keys, 0, NKEYS * sizeof(ScanKeyData));
for(int i = 0; i < n; i++)
{
idx = version1(NKEYS, keys);
free(idx);
}
free(keys);
}
void test2(int n)
{
ScanKeyData *keys;
ScanKeyData *idx;
keys = (ScanKeyData *) malloc(NKEYS * sizeof(ScanKeyData));
memset(keys, 0, NKEYS * sizeof(ScanKeyData));
for(int i = 0; i < n; i++)
{
idx = version2(NKEYS, keys);
free(idx);
}
free(keys);
}
int main(void)
{
struct timespec start,end;
int64_t version1_time, version2_time;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
test1(LOOPS);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
version1_time = get_clock_diff(&end, &start);
printf("version1: done in %lld nanoseconds\n", version1_time);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
test2(LOOPS);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
version2_time = get_clock_diff(&end, &start);
printf("version2: done in %lld nanoseconds\n", version2_time);
printf("(%g times faster)\n", (double) version1_time / version2_time);
return 0;
}