SPO600 Project – inet/ether_line.c

Function: ether_line()

int
     ether_line(const char *l, struct ether_addr *e, char *hostname);
The function ether_line() scans l,an ASCII string in ethers(5) format
     and sets e	to the ethernet	address	specified in the string	and h to the
     hostname.	This function is used to parse lines from /etc/ethers into
     their component parts.
The ether_line() function returns zero on success and non-zero if it was
     unable to parse any part of the supplied line l.  It returns the
     extracted ethernet	address	in the supplied	ether_addr structure e and the
     hostname in the supplied string h.

source code can be found here: https://github.com/lawrencereyes/spo600-glibc/blob/master/inet/ether_line.c

So my first thought when I saw the source code for the function was to improve the loop that was checking each octet of the string in ether form is was being passed. I found two problems when it came to optimizing this part of the code. First, the for loop runs only 6 time. Because of this, vectorizing the for loop through in-line assembly would make the code run slower than it runs now. Second, the while loop that checks for the host-name is also way too simple to try and vectorize it. Since, I could not think of any other type of optimization in the code i decided to test it to see how well it ran in AArch64. These were my results:

#include
#include
#include <netinet/ether.h>
#include

static int
do_test (const char *line)
{
struct ether_addr a;
char buf[1000];
if (ether_line (line, &a, buf) != 0)
{
puts (“ether_line failed”);
return 1;
}

int res = 0;
int i;
for (i = 0; i < ETH_ALEN; ++i)
{
printf (“%02x%s”,
(int) a.ether_addr_octet[i], i + 1 == ETH_ALEN ? “” : “:”);
if (a.ether_addr_octet[i] != i)
{
printf (“octet %d is %d, expected %d\n”,
i, (int) a.ether_addr_octet[i], i);
res = 1;
}
}

//printf (” \”%s\”\n”, buf);
//res |= strcmp (buf, “asdasdgasdgasdgasdfgasdfgasdgvsdfbvsdfbsdfgbsdfgffa”) != 0;

return res;
}

int
main(void)
{
const char *line[10];
line[0] = ” 01:02:03:04:05:06 asdffa\n”;
line[1] = “00:02:03:04:05:06 asdffa\n”;
line[2] = “01:02:03:04:05:06 asdffa\n”;
line[3] = ” 00:01:02:03:04:05 asdasdgasdgasdgasdfgasdfgasdgvsdfbvsdfbsdfgbsdfgffa\n”;
line[4] = “01:02:03:04:05:06 asdffa\n”;
line[5] = “01:02:03:03:05:06 asdffa\n”;
line[6] = “01:01:03:04:05:06 asdffa\n”;
line[7] = “01:02:03:04:05:06 asdffa\n”;
line[8] = “01:02:03:04:05:06 assdgasdgasdgasdgasgdffa\n”;
line[9] = “00:01:02:03:04:05 asdgfasdfasdgasdfgasdfgasdfga asdffa\n”;

int res[10] = {0};
int i = 0;
clock_t start, end;
double time;

start = clock();
for(; i < 10; i++)
{
res[i] = do_test(line[i]);
printf(“Results: %d\n\n”, res[i]);
}
end = clock();
time = ((double) (end – start)) / CLOCKS_PER_SEC;
printf(“time: %.50f\n”, time);
}

This is the test file I used. I modified the current test file for the function, and made it so it would check 10 different addresses.

Command: gcc tst-ether_line.c

ether_line failed
Results: 1

00:02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

01:octet 0 is 1, expected 0
02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

ether_line failed
Results: 1

01:octet 0 is 1, expected 0
02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

01:octet 0 is 1, expected 0
02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
03:05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

01:octet 0 is 1, expected 0
01:03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

01:octet 0 is 1, expected 0
02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

01:octet 0 is 1, expected 0
02:octet 1 is 2, expected 1
03:octet 2 is 3, expected 2
04:octet 3 is 4, expected 3
05:octet 4 is 5, expected 4
06octet 5 is 6, expected 5
Results: 1

00:01:02:03:04:05Results: 0

time: 0.00000000000000000000000000000000000000000000000000

real 0m0.001s
user 0m0.000s
sys 0m0.000s

As you can see, even with just the minimum optimization options from the compiler the code took less than a second to work. if you notice the time value above you can see that I tried to output if it would even take longer than the 50th of a second but it did not show anything. From this, I concluded that this function was not possible to be optimized in any way in this architecture.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s