git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] block-sha1: more good unaligned memory access candidates

From
Nicolas Pitre <nico@cam.org>
Date
Aug 13, 2009, 21:28 UTC
Message-ID
<alpine.LFD.2.00.0908131651110.10633@xanadu.home>
In-Reply-To
<20090813201542.25431.qmail@science.horizon.com>
On Thu, 13 Aug 2009, George Spelvin wrote:
Show 7 quoted lines
> > Wow.  Is it now faster than the arm/ and ppc/ hand-tweaked assembly?
> 
> It's probably faster than the ARM, which was tuned for size rather
> than speed, but if you want to rework the assembly for speed, the ARM's
> rotate-and-add operations allow tricks which I doubt GCC can pick up on.
> (You have to notice that the F(b,c,d) function is bitwise, so you can
> do it on rotated data and do the rotate when you add the result to e.)

gcc is not too bad at merging ALU and shift/rotate operations into the same instruction. However, to make a really optimal ARM version, some custom SHA_ROUND macros with inline assembly could be made. I suspect that wouldn't gain much though, as the pure shift/rotate mov instructions really aren't that many in the generated code.

> I'd be surprised if it were faster than PPC code, especially on the
> in-order G3 and G4 cores where careful scheduling really pays off.
> But maybe I just get to be surprised...

Given that PPC has enough register to hold the entire state, it is then only a matter of proper instruction scheduling which modern gcc ought to do right. If not then this is a good test case for gcc people to fix the PPC machine pipeline description.

> For automatic assembly tuning, I was thinking of having a .c file that
> has a bunch of #ifdef __PPC__ statements that gets run through $(CC) -E.
> That should be a fairly portable way to 
??
Show 41 quoted lines
> The other question about unaligned access is whether it's beneficial
> to make the fetch loop work like this:
> 
> 	char const *in;
> 	uint32_t *out
> 	unsigned lsb = (unsigned)p & 3;
> 	uint32_t const *p32 = (uint32_t const *)(in - lsb);
> 	uint32_t t = ntohl(*p32);
> 
> 	switch (lsb) {
> 
> 	case 0:
> 		*out++ = t;
> 		for (i = 1; i < 16; i++)
> 			*out++ = ntohl(*++p32);
> 		break;
> 	case 1:
> 		for (i = 0; i < 16; i++) {
> 			uint32_t s = t << 8;
> 			t = ntohl(*++p32);
> 			*out++ = s | t >> 24;
> 		}
> 		break;
> 	case 1:
> 		for (i = 0; i < 16; i++) {
> 			uint32_t s = t << 16;
> 			t = ntohl(*++p32);
> 			*out++ = s | t >> 16;
> 		}
> 		break;
> 	case 1:
> 		for (i = 0; i < 16; i++) {
> 			uint32_t s = t << 24;
> 			t = ntohl(*++p32);
> 			*out++ = s | t >> 8;
> 		}
> 		break;
> 	}
> 
> On the ARM, at least, ntohl() isn't particularly cheap, so loading 4
> bytes and assembling them turns out to be cheaper.  But it's a thought.

Well, that would have to be tested. This could possibly only be a gain if you have a fast ntohl() though.

And the other question is also to decide when this is good enough for a generic version. Gaining 5% speedup on raw SHA1 throughput with ugly code might not be worth the maintenance hassle. At that point you might as well go back to a purely asm version if you really want to get the extra edge.

Nicolas
Previous: George Spelvin
Message 2 of 2 in “Re: [PATCH] block-sha1: more good unaligned memory access candidates”
  1. George SpelvinAug 13, 2009
  2. Nicolas PitreAug 13, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.