> On Aug 28, 2015, at 10:54 AM, Ben Pfaff <b...@nicira.com> wrote: > > On Thu, Aug 27, 2015 at 06:29:16PM -0700, Jarno Rajahalme wrote: >> Define struct eth_addr and use it instead of a uint8_t array for all >> ethernet addresses in OVS userspace. The struct is always the right >> size, and it can be assigned without an explicit memcpy, which makes >> code more readable. >> >> "struct eth_addr" is a good type name for this as many utility >> functions are already named accordingly. >> >> struct eth_addr can be accessed as bytes as well as ovs_be16's, which >> makes the struct 16-bit aligned. All use seems to be 16-bit aligned, >> so some algorithms on the ethernet addresses can be made a bit more >> efficient making use of this fact. >> >> As the struct fits into a register (in 64-bit systems) we pass it by >> value when possible. >> >> This patch also changes the few uses of Linux specific ETH_ALEN to >> OVS's own ETH_ADDR_LEN, and removes the OFP_ETH_ALEN, as it is no >> longer needed. >> >> This work stemmed from a desire to make all struct flow members >> assignable for unrelated exploration purposes. However, I think this >> might be a nice code readability improvement by itself. >> >> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > > I like this. I've thought about doing the same thing before and never > got around to it. > > I checked your claim about passing by value by looking at the x86-64 > ABI. It's true! Older ABIs were not so flexible--for example, I seem > to recall that Borland C++ __fastcall ABI for Win32 would pass 1 and 2 > and 4 byte structs in a register, but not 3-byte ones. > > However, GCC is almost criminally bad at optimizing it: > > blp@sigabrt:~/nicira/ovs/_build(0)$ cat tmp.c > struct x { > union { > unsigned char b[6]; > unsigned short w[3]; > }; > }; > void g(struct x); > void f(void) > { > struct x y = { { { 1, 2, 3, 4, 5, 6 } } }; > g(y); > } > > blp@sigabrt:~/nicira/ovs/_build(0)$ gcc -O2 -g -m64 -c tmp.c > blp@sigabrt:~/nicira/ovs/_build(0)$ objdump -dr tmp.o > > tmp.o: file format elf64-x86-64 > > > Disassembly of section .text: > > 0000000000000000 <f>: > 0: 48 83 ec 18 sub $0x18,%rsp > 4: c6 04 24 01 movb $0x1,(%rsp) > 8: c6 44 24 01 02 movb $0x2,0x1(%rsp) > d: c6 44 24 02 03 movb $0x3,0x2(%rsp) > 12: c6 44 24 03 04 movb $0x4,0x3(%rsp) > 17: c6 44 24 04 05 movb $0x5,0x4(%rsp) > 1c: c6 44 24 05 06 movb $0x6,0x5(%rsp) > 21: 48 8b 3c 24 mov (%rsp),%rdi > 25: e8 00 00 00 00 callq 2a <f+0x2a> > 26: R_X86_64_PC32 g-0x4 > 2a: 48 83 c4 18 add $0x18,%rsp > 2e: c3 retq > > Clang does better: > > blp@sigabrt:~/nicira/ovs/_build(0)$ clang -O2 -g -m64 -c tmp.c > blp@sigabrt:~/nicira/ovs/_build(0)$ objdump -dr tmp.o > > tmp.o: file format elf64-x86-64 > > > Disassembly of section .text: > > 0000000000000000 <f>: > 0: 48 bf 01 02 03 04 05 movabs $0x60504030201,%rdi > 7: 06 00 00 > a: e9 00 00 00 00 jmpq f <f+0xf> > b: R_X86_64_PC32 g-0x4 >
One would hope that GCC would do a better job when inlining, though? > Acked-by: Ben Pfaff <b...@nicira.com <mailto:b...@nicira.com>> Thanks for the review. Unfortunately I forgot to add your Acked-by to the commit message, and I realized that just after pushing to github - now I don’t have anyone to shift blame to if builds start failing… Jarno _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev