Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #14925 > unrolled thread
| Started by | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| First post | 2011-12-23 18:43 +0000 |
| Last post | 2012-01-10 18:00 +0100 |
| Articles | 20 on this page of 109 — 24 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2012-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]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2012-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]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2012-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2012-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