Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #14925 > unrolled thread

Performance of hand-optimised assembly

Started byBen Bacarisse <ben.usenet@bsb.me.uk>
First post2011-12-23 18:43 +0000
Last post2012-01-10 18:00 +0100
Articles 20 on this page of 109 — 24 participants

Back to article view | Back to comp.lang.c


Contents

  Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-23 18:43 +0000
    Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-23 19:40 +0000
      Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-23 21:26 +0000
        Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-23 22:02 +0000
          Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-24 02:52 +0000
            Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-23 20:32 -0800
              Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 13:09 +0000
                Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-24 05:49 -0800
                  Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 15:30 +0000
                    Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-24 08:15 -0800
                      Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 17:10 +0000
                        Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-24 23:25 +0000
                          Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2012-01-04 03:24 +0000
                            Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-04 09:59 +0100
                              Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2012-01-04 20:57 +0000
                              Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2012-01-04 23:04 +0000
                  Re: Performance of hand-optimised assembly Noob <root@127.0.0.1> - 2012-01-05 13:32 +0100
                Re: Performance of hand-optimised assembly Philip Lantz <prl@canterey.us> - 2011-12-24 15:29 -0800
            Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 12:42 +0000
              Re: Performance of hand-optimised assembly Jens Gustedt <jens.gustedt@loria.fr> - 2011-12-24 16:58 +0100
            Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 13:55 +0000
              Re: Performance of hand-optimised assembly Seebs <usenet-nospam@seebs.net> - 2011-12-24 19:24 +0000
                Re: Performance of hand-optimised assembly Geoff <geoff@invalid.invalid> - 2011-12-24 13:44 -0800
              Re: Performance of hand-optimised assembly Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-12-29 02:53 +0200
                Re: Performance of hand-optimised assembly Rui Maciel <rui.maciel@gmail.com> - 2011-12-29 02:11 +0000
    Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2011-12-24 01:36 +0000
    Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2011-12-24 06:44 +0100
      Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2011-12-24 09:52 +0100
      Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2011-12-26 08:05 +0100
        Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-26 11:52 -0800
          Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2011-12-27 07:28 +0100
    Re: Performance of hand-optimised assembly Willem <willem@toad.stack.nl> - 2011-12-24 12:48 +0000
      Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-24 04:56 -0800
      Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-24 23:39 +0000
    Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-24 06:01 -0800
      Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-24 14:55 +0000
        Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-28 03:46 -0800
          Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-28 04:52 -0800
      Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-25 00:07 +0000
        Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-28 03:21 -0800
          Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-28 13:19 +0000
            Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-28 16:01 +0000
              Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-28 17:45 +0000
                Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-28 18:56 -0800
              Re: Performance of hand-optimised assembly Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-12-29 03:32 +0200
              Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 17:03 -0800
                Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-26 22:08 +0000
                  Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 22:20 -0800
          Re: Performance of hand-optimised assembly James Kuyper <jameskuyper@verizon.net> - 2011-12-28 08:24 -0500
          Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-28 14:27 +0000
            Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 16:50 -0800
              Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-26 21:59 +0000
          Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-28 11:12 -0800
          Re: Performance of hand-optimised assembly Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-12-29 03:12 +0200
            Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-29 10:02 +0100
              Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-29 12:06 +0000
              Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 17:07 -0800
                Re: Performance of hand-optimised assembly Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-13 01:18 +0200
                  Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 10:54 -0800
            Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-29 10:02 +0100
            Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-29 12:06 +0000
              Re: Performance of hand-optimised assembly Keith Thompson <kst-u@mib.org> - 2011-12-29 11:44 -0800
              Re: Performance of hand-optimised assembly Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 17:23 -0800
            Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2011-12-29 08:37 -0800
              Re: Performance of hand-optimised assembly Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-01-05 22:19 +0200
    Re: Performance of hand-optimised assembly James Dow Allen <gmail@jamesdowallen.nospam> - 2011-12-24 16:21 +0000
      Re: Performance of hand-optimised assembly Weland <weland@otaku.freeshell.org> - 2011-12-25 10:54 +0000
    Re: Performance of hand-optimised assembly "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-12-24 14:52 -0800
    Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-25 20:12 +0100
      Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-25 11:36 -0800
        Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-25 21:35 +0100
          Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2011-12-26 14:24 -0600
            Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-26 21:36 +0100
              Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2012-01-04 11:59 -0600
                Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-04 20:22 +0100
                  Re: Performance of hand-optimised assembly Dann Corbit <dcorbit@connx.com> - 2012-01-04 12:59 -0800
                    Re: Performance of hand-optimised assembly James Harris <james.harris.1@googlemail.com> - 2012-01-04 15:32 -0800
                      Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2012-01-05 23:47 -0600
                  Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-04 22:47 +0000
                    Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-05 00:47 +0100
                      Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-05 00:22 +0000
                        Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2012-01-04 23:44 -0800
                        Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2012-01-05 12:16 +0000
                          Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2012-01-05 12:49 +0000
                        Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2012-01-05 21:26 +0000
                        Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2012-01-07 10:32 +0100
                    Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-05 00:58 +0100
                  Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2012-01-05 13:39 -0800
                    Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2012-01-07 02:15 -0800
                      Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2012-01-10 01:07 -0800
                  Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2012-01-07 00:49 +0000
                    Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-07 08:54 +0100
                      Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-07 10:11 +0100
                        Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2012-01-07 10:51 +0100
                        Re: Performance of hand-optimised assembly jgk@panix.com (Joe keane) - 2012-01-07 20:09 +0000
          Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2012-01-06 23:39 -0600
            Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2012-01-07 10:33 +0100
              Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2012-01-07 07:36 -0600
                Re: Performance of hand-optimised assembly Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-07 21:03 +0000
                  Re: Performance of hand-optimised assembly Stephen Sprunk <stephen@sprunk.org> - 2012-01-07 16:42 -0600
      Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-25 20:23 +0000
        Re: Performance of hand-optimised assembly jacob navia <jacob@spamsink.net> - 2011-12-25 21:50 +0100
          Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-25 22:10 +0000
        Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-25 13:11 -0800
          Re: Performance of hand-optimised assembly "BartC" <bc@freeuk.com> - 2011-12-25 22:07 +0000
            Re: Performance of hand-optimised assembly 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-25 16:39 -0800
    Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2011-12-26 05:55 +0100
      Re: Performance of hand-optimised assembly "io_x" <a@b.c.invalid> - 2012-02-17 17:58 +0100
    Re: Performance of hand-optimised assembly "Wolfgang.Draxinger" <Wolfgang.Draxinger@physik.uni-muenchen.de> - 2012-01-10 18:00 +0100

Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6  Next page →


#15433

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-01-05 00:22 +0000
Message-ID<0.7163c7a5dd6c98958adf.20120105002252GMT.87boqj6lr7.fsf@bsb.me.uk>
In reply to#15427
jacob navia <jacob@spamsink.net> writes:

> Le 04/01/12 23:47, Ben Bacarisse a écrit :
>> When given the "obvious" C, gcc -O3 produces a function with 63
>> instructions taking up 188 bytes.
>
> Show please...

  void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
  {
       int rest = 64 - AmountToShift;
       vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
       vector[1] = (vector[1] << AmountToShift) | (vector[2] >> rest);
       vector[2] = (vector[2] << AmountToShift) | (vector[3] >> rest);
       vector[3] = (vector[3] << AmountToShift) | (vector[4] >> rest);
       vector[4] = (vector[4] << AmountToShift) | (vector[5] >> rest);
       vector[5] = (vector[5] << AmountToShift) | (vector[6] >> rest);
       vector[6] = (vector[6] << AmountToShift) | (vector[7] >> rest);
       vector[7] = (vector[7] << AmountToShift);
  }

Note the change to unsigned long long.  It's what your code was doing
but your interface had signed integers whose use would give rise
to undefined behaviour.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#15456

From88888 Dihedral <dihedral88888@googlemail.com>
Date2012-01-04 23:44 -0800
Message-ID<4134125.173.1325749450026.JavaMail.geo-discussion-forums@prmw6>
In reply to#15433
Ben Bacarisse於 2012年1月5日星期四UTC+8上午8時22分52秒寫道:
> jacob navia <ja...@spamsink.net> writes:
> 
> > Le 04/01/12 23:47, Ben Bacarisse a écrit :
> >> When given the "obvious" C, gcc -O3 produces a function with 63
> >> instructions taking up 188 bytes.
> >
> > Show please...
> 
>   void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
>   {
>        int rest = 64 - AmountToShift;
>        vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
>        vector[1] = (vector[1] << AmountToShift) | (vector[2] >> rest);
>        vector[2] = (vector[2] << AmountToShift) | (vector[3] >> rest);
>        vector[3] = (vector[3] << AmountToShift) | (vector[4] >> rest);
>        vector[4] = (vector[4] << AmountToShift) | (vector[5] >> rest);
>        vector[5] = (vector[5] << AmountToShift) | (vector[6] >> rest);
>        vector[6] = (vector[6] << AmountToShift) | (vector[7] >> rest);
>        vector[7] = (vector[7] << AmountToShift);
>   }
> 
> Note the change to unsigned long long.  It's what your code was doing
> but your interface had signed integers whose use would give rise
> to undefined behaviour.
> 
> -- 
> Ben.

Thus you are working on a little endian system. 

Accessing those vector[i] in the C compiler generated instructions might 
be quite different from hand-optimized assembly instructions from 
professionals. 
  
 

[toc] | [prev] | [next] | [standalone]


#15461

From"BartC" <bc@freeuk.com>
Date2012-01-05 12:16 +0000
Message-ID<QxgNq.158682$4a.110454@newsfe04.ams2>
In reply to#15433

"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
news:0.7163c7a5dd6c98958adf.20120105002252GMT.87boqj6lr7.fsf@bsb.me.uk...
> jacob navia <jacob@spamsink.net> writes:
>
>> Le 04/01/12 23:47, Ben Bacarisse a écrit :
>>> When given the "obvious" C, gcc -O3 produces a function with 63
>>> instructions taking up 188 bytes.
>>
>> Show please...
>
>  void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
>  {
>       int rest = 64 - AmountToShift;
>       vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
>       vector[1] = (vector[1] << AmountToShift) | (vector[2] >> rest);
>       vector[2] = (vector[2] << AmountToShift) | (vector[3] >> rest);
>       vector[3] = (vector[3] << AmountToShift) | (vector[4] >> rest);
>       vector[4] = (vector[4] << AmountToShift) | (vector[5] >> rest);
>       vector[5] = (vector[5] << AmountToShift) | (vector[6] >> rest);
>       vector[6] = (vector[6] << AmountToShift) | (vector[7] >> rest);
>       vector[7] = (vector[7] << AmountToShift);
>  }

I've tested this in 32-bit mode.

For 100 million iterations, lcc-win32 took at least 5.5 seconds, and gcc up 
to -O2 took at least 4.3 seconds.

Assembly took 2.5 seconds (shifting less than 32 bits), or 3.3 seconds 
(>32). (32 bits exactly took 1.4 seconds.)

However, gcc -O3 took 1.4 to 1.6 seconds (and 0.7 seconds for exactly a 
32-bit shift).

I'm still looking at how it can do that, since my assembly code is pretty 
short! It's obviously using inlining, but function call overheads are only 
0.4 seconds.

The strange thing is that gcc's inline version of ShiftVector is only 80 
instructions, but the ShiftVector code itself is about 250. There are some 
parameter overheads, but not 170 instructions' worth.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#15465

From"BartC" <bc@freeuk.com>
Date2012-01-05 12:49 +0000
Message-ID<01hNq.149689$HA5.67064@newsfe30.ams2>
In reply to#15461
"BartC" <bc@freeuk.com> wrote in message 
news:QxgNq.158682$4a.110454@newsfe04.ams2...

> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message

>>  void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
>>  {
>>       int rest = 64 - AmountToShift;
>>       vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
...

> I've tested this in 32-bit mode.

> However, gcc -O3 took 1.4 to 1.6 seconds (and 0.7 seconds for exactly a 
> 32-bit shift).

gcc -O3 was obviously taking advantage of some aspect of the repetitive 
nature of my simple benchmark.

Varying the amount of shift in each iteration soon put paid to that!

Timings for 100 million iterations of a varying number of shifts (1 to 63) 
are now:

gcc -O3 4.7 seconds
lccwin-33 -O 6.6 seconds
PellesC -Ot 6.8 seconds
DMC -o 12.4 seconds
My ASM 3.2 seconds

(And the Asm could do with some further work, this is just the first draft, 
but I'm not going to bother. Having to logically swap alternate 32-bit words 
in order to match the behaviour of 64-bits has already done my head in..)

So as it stands, the advantage of Asm over gcc -o3 is pretty much what 
you've already found.

-- 
Bartc

 

[toc] | [prev] | [next] | [standalone]


#15472

Fromjgk@panix.com (Joe keane)
Date2012-01-05 21:26 +0000
Message-ID<je54io$t8r$1@reader1.panix.com>
In reply to#15433
In article <0.7163c7a5dd6c98958adf.20120105002252GMT.87boqj6lr7.fsf@bsb.me.uk>,
Ben Bacarisse  <ben.usenet@bsb.me.uk> wrote:
>  void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
>  {
>       int rest = 64 - AmountToShift;
>       vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
>       vector[1] = (vector[1] << AmountToShift) | (vector[2] >> rest);
>       vector[2] = (vector[2] << AmountToShift) | (vector[3] >> rest);
>       vector[3] = (vector[3] << AmountToShift) | (vector[4] >> rest);
>       vector[4] = (vector[4] << AmountToShift) | (vector[5] >> rest);
>       vector[5] = (vector[5] << AmountToShift) | (vector[6] >> rest);
>       vector[6] = (vector[6] << AmountToShift) | (vector[7] >> rest);
>       vector[7] = (vector[7] << AmountToShift);
>  }

I spent a bunch of time 'optimizing' this code [in C]; everything i did
made it worse!

Here's gcc:

     .file	"shi.c"
     .text
     .p2align 4,,15
     .globl   ShiftVector
     .type    ShiftVector, @function
ShiftVector:
.LFB0:
	.cfi_startproc
	movq	8(%rdi), %r9
	movl	$64, %eax
	movq	(%rdi), %r8
	subl	%esi, %eax
	movl	%eax, %ecx
	movq	%r9, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r8
	movl	%eax, %ecx
	orq	%r8, %rdx
	movq	16(%rdi), %r8
	movq	%rdx, (%rdi)
	movq	%r8, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r9
	movl	%eax, %ecx
	orq	%r9, %rdx
	movq	24(%rdi), %r9
	movq	%rdx, 8(%rdi)
	movq	%r9, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r8
	movl	%eax, %ecx
	orq	%r8, %rdx
	movq	32(%rdi), %r8
	movq	%rdx, 16(%rdi)
	movq	%r8, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r9
	movl	%eax, %ecx
	orq	%r9, %rdx
	movq	40(%rdi), %r9
	movq	%rdx, 24(%rdi)
	movq	%r9, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r8
	movl	%eax, %ecx
	orq	%r8, %rdx
	movq	48(%rdi), %r8
	movq	%rdx, 32(%rdi)
	movq	%r8, %rdx
	shrq	%cl, %rdx
	movl	%esi, %ecx
	salq	%cl, %r9
	movl	%eax, %ecx
	orq	%r9, %rdx
	movq	%rdx, 40(%rdi)
	movq	56(%rdi), %rdx
	movq	%rdx, %r9
	shrq	%cl, %r9
	movl	%esi, %ecx
	movq	%r9, %rax
	salq	%cl, %r8
	salq	%cl, %rdx
	orq	%r8, %rax
	movq	%rdx, 56(%rdi)
	movq	%rax, 48(%rdi)
	ret
	.cfi_endproc
.LFE0:
	.size	ShiftVector, .-ShiftVector
	.ident	"GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
	.section      .note.GNU-stack,"",@progbits

[toc] | [prev] | [next] | [standalone]


#15532

From"io_x" <a@b.c.invalid>
Date2012-01-07 10:32 +0100
Message-ID<4f081057$0$1385$4fafbaef@reader1.news.tin.it>
In reply to#15433
"Ben Bacarisse" <ben.usenet@bsb.me.uk> ha scritto nel messaggio
news:0.7163c7a5dd6c98958adf.20120105002252GMT.87boqj6lr7.fsf@bsb.me.uk...
> jacob navia <jacob@spamsink.net> writes:
>
>> Le 04/01/12 23:47, Ben Bacarisse a écrit :
>>> When given the "obvious" C, gcc -O3 produces a function with 63
>>> instructions taking up 188 bytes.
>>
>> Show please...
>
>  void ShiftVector(unsigned long long vector[static 8], int AmountToShift)
>  {
>       int rest = 64 - AmountToShift;
>       vector[0] = (vector[0] << AmountToShift) | (vector[1] >> rest);
>       vector[1] = (vector[1] << AmountToShift) | (vector[2] >> rest);
>       vector[2] = (vector[2] << AmountToShift) | (vector[3] >> rest);
>       vector[3] = (vector[3] << AmountToShift) | (vector[4] >> rest);
>       vector[4] = (vector[4] << AmountToShift) | (vector[5] >> rest);
>       vector[5] = (vector[5] << AmountToShift) | (vector[6] >> rest);
>       vector[6] = (vector[6] << AmountToShift) | (vector[7] >> rest);
>       vector[7] = (vector[7] << AmountToShift);
>  }
>
> Note the change to unsigned long long.  It's what your code was doing
> but your interface had signed integers whose use would give rise
> to undefined behaviour.

i not would use that here [or the compiler asm traslation of that],
nor in this tread 64 bits asm code: i would use
a function use the asm instructions  shrd  edx, ebx, cl
[or shld  edx, ebx, cl i not remember the one right]
in a loop and use well cl
shrd, shld, mul and div has something in common has
one 64 bit output or has one 64 bit input as arg



[toc] | [prev] | [next] | [standalone]


#15429

Fromjacob navia <jacob@spamsink.net>
Date2012-01-05 00:58 +0100
Message-ID<je2p35$kb0$1@speranza.aioe.org>
In reply to#15420
Le 04/01/12 23:47, Ben Bacarisse a écrit :
> jacob navia<jacob@spamsink.net>  writes:
> <snip>
>> But let's forget about that. Look at this.
>>
>> problem:
>>
>> You have a vector of 8 long long integers and you want to shift that
>> vector by a given amount left between 1 and 63 bits.
>>
>> Interface:
>>
>> void ShiftVector(long long *vector, int AmountToShift);
>
> Your are keen to promote C99 so should that not be
>
>    void ShiftVector(long long vector[static 8], int AmountToShift);
>


YESSIR!

:-)

But I am so used to being beaten by my C99 posts that I wrote it in C89.
Now I get beaten because I didn't use C99....


>
> This does not work for me and certainly looks wrong.  I think the last
> two lines before ret should be:
>
>          shlq %cl,%rax
>          movq %rax,56(%rdi)
>
> instead.  If I make that change, the function seems to work when tested.
>

Yes, the actual function is more complicated since there is a header
part in the vector (8 bytes) that you should skip. SInce that
would complicate the function for no reason, I modified the indices by
hand to post it and added a bug doing that.

Thanks for your correction Ben. And, by the way, your assembly is not
THAT rusty as you make us believe...


>> 26 instructions, 97 bytes (!!!)
>>
>> Write that in C and see how big your procedure is, and how slow :-)
>
> When given the "obvious" C, gcc -O3 produces a function with 63
> instructions taking up 188 bytes.
>
> Timing is quite hard because the function is so vary quick, but I get
> about 0.4s for 100 million calls of yours and 0.65s for the C version.
>
> I don't think that's bad, given all the advantages of writing in C.
> Yes, it's 1.63 times slower, but how many programs will be dominated by
> such calls?
>


Well, a floating point package is doing that ALL the time since you must
match the mantissas before doing ANY operation. Matching the mantissas
means shifting them to match the decimal point.


It is one of the central pieces of the package and any performance 
improvement even a extremely small one has BIG consequences.

But I reserve my final opinion until I see what gcc generates and if
my gcc generates that too.


Thanks for your post Ben.

jacob

[toc] | [prev] | [next] | [standalone]


#15475

From88888 Dihedral <dihedral88888@googlemail.com>
Date2012-01-05 13:39 -0800
Message-ID<17628537.415.1325799572104.JavaMail.geo-discussion-forums@prgi2>
In reply to#15412
jacob navia於 2012年1月5日星期四UTC+8上午3時22分25秒寫道:
> Le 04/01/12 18:59, Stephen Sprunk a écrit :
> > On 26-Dec-11 14:36, jacob navia wrote:
> >> Le 26/12/11 21:24, Stephen Sprunk a écrit :
> >>> On 25-Dec-11 14:35, jacob navia wrote:
> >>>> Assembly will always do better than standard C in the above specific
> >>>> code. You can then use the ADDPD and add 2 integers at the same time
> >>>> (under specific loop conditions).
> >>>
> >>> ... unless you have a vectorizing compiler, which will do the exact same
> >>> thing for you without the need for inline assembly.
> >>
> >> Sure. That was a simple example, and no, gcc doesn't do it, at least
> >> in the version I have
> >
> > Like many GCC sub-projects, the work isn't complete, and probably isn't
> > on by default:
> > http://gcc.gnu.org/projects/tree-ssa/vectorization.html
> >
> 
> 
> Note that those instructions are available since at least 10 YEARS
> and still mainstream compilers like MSVC or GCC do not perform any of
> the magic you invoke...
> 
> Sure, maybe ONE DAY IN THE FAR FUTURE they will do it, but until then I
> am using those instructions in my programs now...
> 
> 
> > GCC isn't the only compiler out there, either; I've heard ICC is very
> > good at this, for instance.
> >
> 
> Yes, you need ALLL THE RESOURCES of Intel Corp to build such a compiler,
> no wonder nobody has done that besides Intel.
> 
> >>> Also, when AVX support comes out, that vectorizing compiler will start
> >>> using AVX instructions while your assembly is stuck using SSE.
> >>
> >> Sure, you can recompile your program bu I can't change a few loop
> >> `conditions since I am "stuck" with my old program, poor me.
> >
> > AVX will be different instructions, different registers, etc.
> 
> What?
> 
> Look Stephen, you are surely knowledgable in C but in assembly...
> Take for instance ANDPS (AND NOT PACKED Single precision)
> 
> The corresponding AVX instructions is...
> VANDNPS, with the same syntax same semantics. You just
> add a "V" before the instruction mnemonic.
> 
> All you have to do is use the ymm registers with 256 bits
> instead of the xmm registers with 128 bits. Your loop
> counters must be adjusted (using only half as many loops)
> and that was it, maybe an hour of work for a big program.
> 
> 
> > It won't
> > be a complete rewrite from scratch, but it'll be a lot of work, whereas
> > someone with a vectorizing compiler can just change one option and
> > recompile.
> >
> 
> Yes, but it will be at least 10 years before gcc or MSVC propose that.
> gcc doesn't even propose automatically SSE2 or SSE3 TODAY, 10 years
> after it was announced by Intel...
> 
> 
> >>> Furthermore, there is no guaranteed win for using SEE; early SSE chips
> >>> simply decoded that into two FADDs, so there was no performance benefit
> >>> to all that work you invested in writing SSE assembly.
> >>
> 
> That was in 2000, when it first appeared. Pleeeeeze, we are 2012 now,
> that is no longer relevant at all.
> 
> 
> But let's forget about that. Look at this.
> 
> problem:
> 
> You have a vector of 8 long long integers and you want to shift that
> vector by a given amount left between 1 and 63 bits.
> 
> Interface:
> 
> void ShiftVector(long long *vector, int AmountToShift);
> ; Pointer to vector in %rdi
> ; Amount to shift in %rsi
> ; gcc calling conventions for x86-64
> shiftvector:
>          movq    %rsi,%rcx 
 AmountToShift -> rcx

> 
>          movq (%rdi),%rsi

vector[0] -> rsi
>          movq 8(%rdi),%rax
vector[1] -> rax
>          shldq %cl,%rax,%rsi

Do the shift to the left.  

>          movq %rsi,(%rdi)

Save the rsi part.  Leave the rax part. 
> 
>          movq 16(%rdi),%rsi
vector[2] -> rsi


>          shldq %cl,%rsi,%rax
Do the shift. 
>          movq %rax,8(%rdi)

Save the rax part. Leave the rsi part. 

> 
>          movq 24(%rdi),%rax
>          shldq %cl,%rax,%rsi
>          movq %rsi,16(%rdi)
> 
>          movq 32(%rdi),%rsi
>          shldq %cl,%rsi,%rax
>          movq %rax,24(%rdi)
> 
>          movq 40(%rdi),%rax
>          shldq %cl,%rax,%rsi
>          movq %rsi,32(%rdi)
> 
>          movq 48(%rdi),%rsi
>          shldq %cl,%rsi,%rax
>          movq %rax,40(%rdi)
> 
>          movq 56(%rdi),%rax
>          shldq %cl,%rax,%rsi
>          movq %rsi,48(%rdi)
> 
>          shlq %cl,%rsi
>          movq %rsi,56(%rdi)
> 
>          ret
> 
> 26 instructions, 97 bytes (!!!)
> 
> Write that in C and see how big your procedure is, and how slow :-)

[toc] | [prev] | [next] | [standalone]


#15535

From88888 Dihedral <dihedral88888@googlemail.com>
Date2012-01-07 02:15 -0800
Message-ID<16122566.1052.1325931306812.JavaMail.geo-discussion-forums@prak33>
In reply to#15475
88888 Dihedral於 2012年1月6日星期五UTC+8上午5時39分31秒寫道:
> jacob navia於 2012年1月5日星期四UTC+8上午3時22分25秒寫道:
> > Le 04/01/12 18:59, Stephen Sprunk a écrit :
> > > On 26-Dec-11 14:36, jacob navia wrote:
> > >> Le 26/12/11 21:24, Stephen Sprunk a écrit :
> > >>> On 25-Dec-11 14:35, jacob navia wrote:
> > >>>> Assembly will always do better than standard C in the above specific
> > >>>> code. You can then use the ADDPD and add 2 integers at the same time
> > >>>> (under specific loop conditions).
> > >>>
> > >>> ... unless you have a vectorizing compiler, which will do the exact same
> > >>> thing for you without the need for inline assembly.
> > >>
> > >> Sure. That was a simple example, and no, gcc doesn't do it, at least
> > >> in the version I have
> > >
> > > Like many GCC sub-projects, the work isn't complete, and probably isn't
> > > on by default:
> > > http://gcc.gnu.org/projects/tree-ssa/vectorization.html
> > >
> > 
> > 
> > Note that those instructions are available since at least 10 YEARS
> > and still mainstream compilers like MSVC or GCC do not perform any of
> > the magic you invoke...
> > 
> > Sure, maybe ONE DAY IN THE FAR FUTURE they will do it, but until then I
> > am using those instructions in my programs now...
> > 
> > 
> > > GCC isn't the only compiler out there, either; I've heard ICC is very
> > > good at this, for instance.
> > >
> > 
> > Yes, you need ALLL THE RESOURCES of Intel Corp to build such a compiler,
> > no wonder nobody has done that besides Intel.
> > 
> > >>> Also, when AVX support comes out, that vectorizing compiler will start
> > >>> using AVX instructions while your assembly is stuck using SSE.
> > >>
> > >> Sure, you can recompile your program bu I can't change a few loop
> > >> `conditions since I am "stuck" with my old program, poor me.
> > >
> > > AVX will be different instructions, different registers, etc.
> > 
> > What?
> > 
> > Look Stephen, you are surely knowledgable in C but in assembly...
> > Take for instance ANDPS (AND NOT PACKED Single precision)
> > 
> > The corresponding AVX instructions is...
> > VANDNPS, with the same syntax same semantics. You just
> > add a "V" before the instruction mnemonic.
> > 
> > All you have to do is use the ymm registers with 256 bits
> > instead of the xmm registers with 128 bits. Your loop
> > counters must be adjusted (using only half as many loops)
> > and that was it, maybe an hour of work for a big program.
> > 
> > 
> > > It won't
> > > be a complete rewrite from scratch, but it'll be a lot of work, whereas
> > > someone with a vectorizing compiler can just change one option and
> > > recompile.
> > >
> > 
> > Yes, but it will be at least 10 years before gcc or MSVC propose that.
> > gcc doesn't even propose automatically SSE2 or SSE3 TODAY, 10 years
> > after it was announced by Intel...
> > 
> > 
> > >>> Furthermore, there is no guaranteed win for using SEE; early SSE chips
> > >>> simply decoded that into two FADDs, so there was no performance benefit
> > >>> to all that work you invested in writing SSE assembly.
> > >>
> > 
> > That was in 2000, when it first appeared. Pleeeeeze, we are 2012 now,
> > that is no longer relevant at all.
> > 
> > 
> > But let's forget about that. Look at this.
> > 
> > problem:
> > 
> > You have a vector of 8 long long integers and you want to shift that
> > vector by a given amount left between 1 and 63 bits.
> > 
> > Interface:
> > 
> > void ShiftVector(long long *vector, int AmountToShift);
> > ; Pointer to vector in %rdi
> > ; Amount to shift in %rsi
> > ; gcc calling conventions for x86-64
> > shiftvector:
> >          movq    %rsi,%rcx 
>  AmountToShift -> rcx
> 
> > 
> >          movq (%rdi),%rsi
> 
> vector[0] -> rsi
> >          movq 8(%rdi),%rax
> vector[1] -> rax
> >          shldq %cl,%rax,%rsi
> 
> Do the shift to the left.  

the (rax, rsi) bit shifted result  in rsi  and rax not changed
> 
> >          movq %rsi,(%rdi)
> 
> Save the rsi part.  Leave the rax part. 
> > 
> >          movq 16(%rdi),%rsi
> vector[2] -> rsi
> 
> 
> >          shldq %cl,%rsi,%rax
> Do the shift. 

the (rsi, rax) bit shifted result  in rax  and rsi not changed
if there's an instruction to do this directly  


> >          movq %rax,8(%rdi)
> 
> Save the rax part. Leave the rsi part. 
> 


> > 
> >          movq 24(%rdi),%rax
> >          shldq %cl,%rax,%rsi
> >          movq %rsi,16(%rdi)
> > 
> >          movq 32(%rdi),%rsi
> >          shldq %cl,%rsi,%rax
> >          movq %rax,24(%rdi)
> > 
> >          movq 40(%rdi),%rax
> >          shldq %cl,%rax,%rsi
> >          movq %rsi,32(%rdi)
> > 
> >          movq 48(%rdi),%rsi
> >          shldq %cl,%rsi,%rax
> >          movq %rax,40(%rdi)
> > 
> >          movq 56(%rdi),%rax
> >          shldq %cl,%rax,%rsi
> >          movq %rsi,48(%rdi)
> > 
> >          shlq %cl,%rsi
> >          movq %rsi,56(%rdi)
> > 
> >          ret
> > 
> > 26 instructions, 97 bytes (!!!)
> > 
> > Write that in C and see how big your procedure is, and how slow :-)

[toc] | [prev] | [next] | [standalone]


#15681

From88888 Dihedral <dihedral88888@googlemail.com>
Date2012-01-10 01:07 -0800
Message-ID<22636092.226.1326186434985.JavaMail.geo-discussion-forums@prmu37>
In reply to#15535
88888 Dihedral於 2012年1月7日星期六UTC+8下午6時15分06秒寫道:
> 88888 Dihedral於 2012年1月6日星期五UTC+8上午5時39分31秒寫道:
> > jacob navia於 2012年1月5日星期四UTC+8上午3時22分25秒寫道:
> > > Le 04/01/12 18:59, Stephen Sprunk a écrit :
> > > > On 26-Dec-11 14:36, jacob navia wrote:
> > > >> Le 26/12/11 21:24, Stephen Sprunk a écrit :
> > > >>> On 25-Dec-11 14:35, jacob navia wrote:
> > > >>>> Assembly will always do better than standard C in the above specific
> > > >>>> code. You can then use the ADDPD and add 2 integers at the same time
> > > >>>> (under specific loop conditions).
> > > >>>
> > > >>> ... unless you have a vectorizing compiler, which will do the exact same
> > > >>> thing for you without the need for inline assembly.
> > > >>
> > > >> Sure. That was a simple example, and no, gcc doesn't do it, at least
> > > >> in the version I have
> > > >
> > > > Like many GCC sub-projects, the work isn't complete, and probably isn't
> > > > on by default:
> > > > http://gcc.gnu.org/projects/tree-ssa/vectorization.html
> > > >
> > > 
> > > 
> > > Note that those instructions are available since at least 10 YEARS
> > > and still mainstream compilers like MSVC or GCC do not perform any of
> > > the magic you invoke...
> > > 
> > > Sure, maybe ONE DAY IN THE FAR FUTURE they will do it, but until then I
> > > am using those instructions in my programs now...
> > > 
> > > 
> > > > GCC isn't the only compiler out there, either; I've heard ICC is very
> > > > good at this, for instance.
> > > >
> > > 
> > > Yes, you need ALLL THE RESOURCES of Intel Corp to build such a compiler,
> > > no wonder nobody has done that besides Intel.
> > > 
> > > >>> Also, when AVX support comes out, that vectorizing compiler will start
> > > >>> using AVX instructions while your assembly is stuck using SSE.
> > > >>
> > > >> Sure, you can recompile your program bu I can't change a few loop
> > > >> `conditions since I am "stuck" with my old program, poor me.
> > > >
> > > > AVX will be different instructions, different registers, etc.
> > > 
> > > What?
> > > 
> > > Look Stephen, you are surely knowledgable in C but in assembly...
> > > Take for instance ANDPS (AND NOT PACKED Single precision)
> > > 
> > > The corresponding AVX instructions is...
> > > VANDNPS, with the same syntax same semantics. You just
> > > add a "V" before the instruction mnemonic.
> > > 
> > > All you have to do is use the ymm registers with 256 bits
> > > instead of the xmm registers with 128 bits. Your loop
> > > counters must be adjusted (using only half as many loops)
> > > and that was it, maybe an hour of work for a big program.
> > > 
> > > 
> > > > It won't
> > > > be a complete rewrite from scratch, but it'll be a lot of work, whereas
> > > > someone with a vectorizing compiler can just change one option and
> > > > recompile.
> > > >
> > > 
> > > Yes, but it will be at least 10 years before gcc or MSVC propose that.
> > > gcc doesn't even propose automatically SSE2 or SSE3 TODAY, 10 years
> > > after it was announced by Intel...
> > > 
> > > 
> > > >>> Furthermore, there is no guaranteed win for using SEE; early SSE chips
> > > >>> simply decoded that into two FADDs, so there was no performance benefit
> > > >>> to all that work you invested in writing SSE assembly.
> > > >>
> > > 
> > > That was in 2000, when it first appeared. Pleeeeeze, we are 2012 now,
> > > that is no longer relevant at all.
> > > 
> > > 
> > > But let's forget about that. Look at this.
> > > 
> > > problem:
> > > 
> > > You have a vector of 8 long long integers and you want to shift that
> > > vector by a given amount left between 1 and 63 bits.
> > > 
> > > Interface:
> > > 
> > > void ShiftVector(long long *vector, int AmountToShift);
> > > ; Pointer to vector in %rdi
> > > ; Amount to shift in %rsi
> > > ; gcc calling conventions for x86-64
> > > shiftvector:
> > >          movq    %rsi,%rcx 
> >  AmountToShift -> rcx
> > 
> > > 
> > >          movq (%rdi),%rsi
> > 
> > vector[0] -> rsi
> > >          movq 8(%rdi),%rax
> > vector[1] -> rax
> > >          shldq %cl,%rax,%rsi
> > 
> > Do the shift to the left.  
> 
> the (rax, rsi) bit shifted result  in rsi  and rax not changed
> > 
> > >          movq %rsi,(%rdi)
> > 
> > Save the rsi part.  Leave the rax part. 
> > > 
> > >          movq 16(%rdi),%rsi
> > vector[2] -> rsi
> > 
> > 
> > >          shldq %cl,%rsi,%rax
> > Do the shift. 
> 
> the (rsi, rax) bit shifted result  in rax  and rsi not changed
> if there's an instruction to do this directly  
> 
> 
> > >          movq %rax,8(%rdi)
> > 
> > Save the rax part. Leave the rsi part. 
> > 
> 
> 
> > > 
> > >          movq 24(%rdi),%rax
> > >          shldq %cl,%rax,%rsi
> > >          movq %rsi,16(%rdi)
> > > 
> > >          movq 32(%rdi),%rsi
> > >          shldq %cl,%rsi,%rax
> > >          movq %rax,24(%rdi)
> > > 
> > >          movq 40(%rdi),%rax
> > >          shldq %cl,%rax,%rsi
> > >          movq %rsi,32(%rdi)
> > > 
> > >          movq 48(%rdi),%rsi
> > >          shldq %cl,%rsi,%rax
> > >          movq %rax,40(%rdi)
> > > 
> > >          movq 56(%rdi),%rax
> > >          shldq %cl,%rax,%rsi
> > >          movq %rsi,48(%rdi)
> > > 
> > >          shlq %cl,%rsi
> > >          movq %rsi,56(%rdi)
> > > 
> > >          ret
> > > 
> > > 26 instructions, 97 bytes (!!!)
> > > 
> > > Write that in C and see how big your procedure is, and how slow :-)

RBI, RCI,  and REI not used, thus it's possible to speed  up more
by dual or quadro-cores in X86. 

[toc] | [prev] | [next] | [standalone]


#15516

Fromjgk@panix.com (Joe keane)
Date2012-01-07 00:49 +0000
Message-ID<je84q1$evb$1@reader1.panix.com>
In reply to#15412
In article <je28te$g14$1@speranza.aioe.org>,
jacob navia  <jacob@jspamsink.org> wrote:
>You have a vector of 8 long long integers and you want to shift that
>vector by a given amount left between 1 and 63 bits.

I resheduled your code...

new code:
	.text
	.global ShiftVector
ShiftVector:
	movq	0(%rdi),%rax
	movq	8(%rdi),%rdx
	movq	%rsi,%rcx
	pushq	%rbx
	shldq	%cl,%rdx,%rax
	movq	16(%rdi),%rbx
	shldq	%cl,%rbx,%rdx
	movq	%rax,0(%rdi)
	movq	24(%rdi),%rax
	shldq	%cl,%rax,%rbx
	movq	%rdx,8(%rdi)
	movq	32(%rdi),%rdx
	shldq	%cl,%rdx,%rax
	movq	%rbx,16(%rdi)
	movq	40(%rdi),%rbx
	shldq	%cl,%rbx,%rdx
	movq	%rax,24(%rdi)
	movq	48(%rdi),%rax
	shldq	%cl,%rax,%rbx
	movq	%rdx,32(%rdi)
	movq	56(%rdi),%rdx
	shldq	%cl,%rdx,%rax
	movq	%rbx,40(%rdi)
	shlq	%cl,%rdx
	popq	%rbx
	movq	%rax,48(%rdi)
	movq	%rdx,56(%rdi)
	ret

orig [C] 0.535
navia	 0.45
new	 0.38

[toc] | [prev] | [next] | [standalone]


#15524

Fromjacob navia <jacob@spamsink.net>
Date2012-01-07 08:54 +0100
Message-ID<je8to2$7ab$1@speranza.aioe.org>
In reply to#15516
Le 07/01/12 01:49, Joe keane a écrit :
>
> orig [C] 0.535
> navia	 0.45
> new	 0.38

Hey THANKS Joe!

That is a thing I haven't done yet, and should have done before.
It is an important optimization I missed completely.

ASM now comes to a big factor from the C version.

[toc] | [prev] | [next] | [standalone]


#15531

Fromjacob navia <jacob@spamsink.net>
Date2012-01-07 10:11 +0100
Message-ID<je927u$g2m$1@speranza.aioe.org>
In reply to#15524
Le 07/01/12 08:54, jacob navia a écrit :
> Le 07/01/12 01:49, Joe keane a écrit :
>>
>> orig [C] 0.535
>> navia 0.45
>> new 0.38
>
> Hey THANKS Joe!
>
> That is a thing I haven't done yet, and should have done before.
> It is an important optimization I missed completely.
>

What I didn't say is WHY did I missed that.

I am fully aware that scheduling instructions increases performance
but I do that optimization not very often...

The reason is that I have a really bad time understanding my own
programs after I do that. In my own brain circuitry I like to have
logical statements that are ordered logically like:

	do operation 1
	do operation 2
	... etc

Scheduling breaks that, and when you reread the program later
there is a huge MESS where instructions from operations 1 and 2
(and maybe 456) are meshed together to use all available slots
what is great for the machine but terrible for my brain since
to figure out where the bug is, or how could I change that, I
have to mentally separate and detangle the mess.

Somehow I hate doing that, surely because of the way my wires
run in my brain.

And this is one of the weakness of manually programming in
assembler. I wanted to acknowledge that.

Obviously your rescheduling is not THAT bad, since you just use
another register and the program REMAINS quite readable, but
I didn't even do that because my revulsion at scheduling in
general. I think it is a bug in my brain, and it is nice to reflect
as to why I haven't seen it and avoided scheduling completely


Surely, a color editor would help, for instance if I could code
related instructions in a given color, then the next group in another,
that would help me to read the code later when I could follow a color
to group related instructions together...

Again, IDE's are important :-)


[toc] | [prev] | [next] | [standalone]


#15534

From"io_x" <a@b.c.invalid>
Date2012-01-07 10:51 +0100
Message-ID<4f0814ad$0$1389$4fafbaef@reader2.news.tin.it>
In reply to#15531
"jacob navia" <jacob@spamsink.net> ha scritto nel messaggio
news:je927u$g2m$1@speranza.aioe.org...
> Le 07/01/12 08:54, jacob navia a écrit :
>> Le 07/01/12 01:49, Joe keane a écrit :
>>>
>>> orig [C] 0.535
>>> navia 0.45
>>> new 0.38
>>
>> Hey THANKS Joe!
>>
>> That is a thing I haven't done yet, and should have done before.
>> It is an important optimization I missed completely.
>>
>
> What I didn't say is WHY did I missed that.
>
> I am fully aware that scheduling instructions increases performance
> but I do that optimization not very often...
>
> The reason is that I have a really bad time understanding my own
> programs after I do that. In my own brain circuitry I like to have
> logical statements that are ordered logically like:
>
> do operation 1
> do operation 2
> ... etc
>
> Scheduling breaks that, and when you reread the program later
> there is a huge MESS where instructions from operations 1 and 2
> (and maybe 456) are meshed together to use all available slots
> what is great for the machine but terrible for my brain since
> to figure out where the bug is, or how could I change that, I
> have to mentally separate and detangle the mess.
>
> Somehow I hate doing that, surely because of the way my wires
> run in my brain.
>
> And this is one of the weakness of manually programming in
> assembler. I wanted to acknowledge that.

this could be one "weakness" for HLLs too
because sometime
for find-understand one bug-code you have to understand the asm
result down the little operations on registers


[toc] | [prev] | [next] | [standalone]


#15555

Fromjgk@panix.com (Joe keane)
Date2012-01-07 20:09 +0000
Message-ID<jea8q2$hq2$1@reader1.panix.com>
In reply to#15531
In article <je927u$g2m$1@speranza.aioe.org>,
jacob navia  <jacob@jspamsink.org> wrote:
>	do operation 1
>	do operation 2
>	... etc

My brain is warped from reading too much compiler output, so stuff like
this makes sense:

	A part 1
	A part 2
	B part 1
	A part 4
	X part 8
	D part 2

[toc] | [prev] | [next] | [standalone]


#15521

FromStephen Sprunk <stephen@sprunk.org>
Date2012-01-06 23:39 -0600
Message-ID<je8lqu$24b$1@dont-email.me>
In reply to#14992
On 25-Dec-11 14:35, jacob navia wrote:
> Look at this:
> 
> void doADD(double *L, double *R, double *result,size_t n)
> {
>     for(size_t i=0; i<n;i++) result[i]=L[i]+R[i];
> }
> 
> Assembly will always do better than standard C in the above specific
> code. You can then use the ADDPD and add 2 integers at the same time
> (under specific loop conditions).

Really?  I don't know how to get GCC to assume the arrays above are
properly aligned, though I'm sure there's a way.  However, if I change
the code slightly so it knows that, I get this code for the loop:

.L6:
        addl    $1, %edx
        movapd  R(%eax), %xmm0
        addpd   L(%eax), %xmm0
        movapd  %xmm0, result(%eax)
        addl    $16, %eax
        cmpl    %edx, %ecx
        ja      .L6
        cmpl    %esi, %ebx
        je      .L9
.L4:
        leal    L(,%ebx,8), %edx
        xorl    %ecx, %ecx
        movl    %ebx, %eax
        .p2align 4,,7
.L8:
        addl    $1, %ecx
        movsd   (%edx), %xmm0
        addsd   R(,%eax,8), %xmm0
        movsd   %xmm0, result(,%eax,8)
        leal    (%ecx,%ebx), %eax
        addl    $8, %edx
        cmpl    %eax, %esi
        ja      .L8
.L9:

So, GCC on my system _will_ auto-vectorize that loop with the
appropriate flags (-msse2 -fpmath=sse -ftree-vectorize).

I noticed the above isn't unrolled, though, so I added -funroll-loops,
and it happily generated code that used xmm0-xmm7 and would presumably
be much faster, though it's way, way too verbose to post here.

Is your asm version really significantly better than the above?

S


-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#15533

Fromjacob navia <jacob@spamsink.net>
Date2012-01-07 10:33 +0100
Message-ID<je93gh$ij1$1@speranza.aioe.org>
In reply to#15521
Le 07/01/12 06:39, Stephen Sprunk a écrit :
> On 25-Dec-11 14:35, jacob navia wrote:
>> Look at this:
>>
>> void doADD(double *L, double *R, double *result,size_t n)
>> {
>>      for(size_t i=0; i<n;i++) result[i]=L[i]+R[i];
>> }
>>
>> Assembly will always do better than standard C in the above specific
>> code. You can then use the ADDPD and add 2 integers at the same time
>> (under specific loop conditions).
>
> Really?  I don't know how to get GCC to assume the arrays above are
> properly aligned, though I'm sure there's a way.


Maybe, but that is exactly my point. Why couldn't we be able to
DECLARE that those arrays are properly aligned and are suitable
for SIMD processing?

Why should we expect that the compiler implements a HUGE and
brittle machinery to DEDUCE that instead?

Wouldn't it be simpler if we would just be able to declare those
in the same way that we say:
	int i;
instead of expecting the commpiler to DEDUCE that because of the
usage of that variable it must be an int?

See that other thread I started about containers and SIMD
programming.

[toc] | [prev] | [next] | [standalone]


#15540

FromStephen Sprunk <stephen@sprunk.org>
Date2012-01-07 07:36 -0600
Message-ID<je9ho4$he1$1@dont-email.me>
In reply to#15533
On 07-Jan-12 03:33, jacob navia wrote:
> Le 07/01/12 06:39, Stephen Sprunk a écrit :
>> On 25-Dec-11 14:35, jacob navia wrote:
>>> Look at this:
>>>
>>> void doADD(double *L, double *R, double *result,size_t n)
>>> {
>>>      for(size_t i=0; i<n;i++) result[i]=L[i]+R[i];
>>> }
>>>
>>> Assembly will always do better than standard C in the above specific
>>> code. You can then use the ADDPD and add 2 integers at the same time
>>> (under specific loop conditions).
>>
>> Really?  I don't know how to get GCC to assume the arrays above are
>> properly aligned, though I'm sure there's a way.
> 
> Maybe, but that is exactly my point. Why couldn't we be able to
> DECLARE that those arrays are properly aligned and are suitable
> for SIMD processing?

In the code above, there are three pointers, which may or may not be
suitably aligned for SIMD instructions.  If they were declared as arrays
(which is the slight modification I made), the compiler will know
they're aligned.

> Why should we expect that the compiler implements a HUGE and
> brittle machinery to DEDUCE that instead?

It's not huge or brittle; it's just one AND operation and conditional
branch per pointer.  GCC doesn't bother to do it, for reasons I don't
understand, but it is not an unreasonable optimization given the
performance benefits of aligned access.

> Wouldn't it be simpler if we would just be able to declare those
> in the same way that we say:
>     int i;
> instead of expecting the commpiler to DEDUCE that because of the
> usage of that variable it must be an int?

Huh?  What I did was take L, R and result out of the parameter list and
declare them like this:

double L[256], R[256], result[256];

That is sufficient for the compiler to know they're properly aligned,
unlike a (double *).

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#15558

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-01-07 21:03 +0000
Message-ID<0.844037c2eed0e6985d5b.20120107210312GMT.8739br444v.fsf@bsb.me.uk>
In reply to#15540
Stephen Sprunk <stephen@sprunk.org> writes:
> On 07-Jan-12 03:33, jacob navia wrote:
>> Le 07/01/12 06:39, Stephen Sprunk a écrit :
>>> On 25-Dec-11 14:35, jacob navia wrote:
<snip>
>>>> void doADD(double *L, double *R, double *result,size_t n)
>>>> {
>>>>      for(size_t i=0; i<n;i++) result[i]=L[i]+R[i];
>>>> }
<snip>
> In the code above, there are three pointers, which may or may not be
> suitably aligned for SIMD instructions.  If they were declared as arrays
> (which is the slight modification I made), the compiler will know
> they're aligned.

My gcc (4.6.1) generates addpd instructions with only -O3, even when L,
R and result are pointers.  I wonder if the is a gcc version difference
or something to do with my system (64-bit Linux).

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#15561

FromStephen Sprunk <stephen@sprunk.org>
Date2012-01-07 16:42 -0600
Message-ID<jeahp5$aen$1@dont-email.me>
In reply to#15558
On 07-Jan-12 15:03, Ben Bacarisse wrote:
> Stephen Sprunk <stephen@sprunk.org> writes:
>> On 07-Jan-12 03:33, jacob navia wrote:
>>> Le 07/01/12 06:39, Stephen Sprunk a écrit :
>>>> On 25-Dec-11 14:35, jacob navia wrote:
> <snip>
>>>>> void doADD(double *L, double *R, double *result,size_t n)
>>>>> {
>>>>>      for(size_t i=0; i<n;i++) result[i]=L[i]+R[i];
>>>>> }
> <snip>
>> In the code above, there are three pointers, which may or may not be
>> suitably aligned for SIMD instructions.  If they were declared as arrays
>> (which is the slight modification I made), the compiler will know
>> they're aligned.
> 
> My gcc (4.6.1) generates addpd instructions with only -O3, even when L,
> R and result are pointers.  I wonder if the is a gcc version difference
> or something to do with my system (64-bit Linux).

Probably; my gcc is 4.2.4, which is a fairly old branch.  I'll see if I
can talk my sysadmin into upgrading.

S


-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web