summaryrefslogtreecommitdiffstats
path: root/Master/Public-Key-Algorithmen/PKA-Prakt1/src/main.c
blob: 29879664eec7158865cc534d75ccc8fc7770f4f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * main.c
 *
 *  Created on: 23.04.2010
 *      Author: sven
 */
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

#define HI(x) (x >> 16)
#define LO(x) (x & 0x0000FFFF)

void mulc(uint32_t *u, uint32_t *v, uint32_t a, uint32_t b)
{
	uint32_t t;
	t = LO(a) * LO(b);
	*v = LO(t);
	t = HI(t) + HI(a) * LO(b);
	*u = HI(t);
	t = LO(t) + LO(a) * HI(b);
	*v |= LO(t) << 16;
	*u += HI(t) + HI(a) * HI(b);
}
void mula(uint32_t *u, uint32_t *v, uint32_t a, uint32_t b)
{
	asm
	(
			"mov %2,%%eax\n"
			"mul %3\n"
			"mov %%edx, %0\n"
			"mov %%eax, %1"
			:"=r"(*u),"=r"(*v)
			:"r"(a),"r"(b)
	);
}
void initRandomizer()
{
	srand(time(NULL));
}
uint32_t getRandomUint32()
{
	uint32_t res = rand();
	if(res % 2)
	{
		return (res | 1<<31);
	}
	return res;
}
int main(int argc, char* argv[])
{
	initRandomizer();
	uint32_t a = getRandomUint32();
	uint32_t b = getRandomUint32();
	uint32_t u,v;
	uint32_t counter;
	uint32_t outerCnt;
	const uint32_t NUM_INNER_LOOPS = 1000000;
	const uint32_t NUM_OUTER_LOOPS = 1000;
	struct timeval startc;
	struct timeval endc;
	struct timeval starta;
	struct timeval enda;
	long diffCsum = 0,diffAsum = 0;
	for(outerCnt=0;outerCnt<NUM_OUTER_LOOPS;outerCnt++) {
		gettimeofday(&startc,0);
		for (counter=0; counter < NUM_INNER_LOOPS; counter++) {
			mulc(&u,&v,a,b);
		}
		gettimeofday(&endc,0);
		diffCsum += (endc.tv_sec*1000000 + endc.tv_usec) - (startc.tv_sec*1000000 + startc.tv_usec);
		printf("C %u * %u = %u.%u\n",a,b,u,v);
		u=0;
		v=0;
		gettimeofday(&starta,0);
		for (counter=0; counter < NUM_INNER_LOOPS; counter++) {
			mula(&u,&v,a,b);
		}
		gettimeofday(&enda,0);
		diffAsum += (enda.tv_sec*1000000 + enda.tv_usec) - (starta.tv_sec*1000000 + starta.tv_usec);
		printf("ASM %u * %u = %u.%u\n",a,b,u,v);
	}
	printf("C: total %ld usec, avg %ld usec\n",diffCsum,(diffCsum / NUM_OUTER_LOOPS));
	printf("ASM: total %ld usec, avg %ld usec\n",diffAsum,(diffAsum / NUM_OUTER_LOOPS));
	return EXIT_SUCCESS;
}