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


Groups > comp.lang.forth > #44782 > unrolled thread

Ruby/Forth challenge for WJ

Started byChris Curl <ccurl609@gmail.com>
First post2016-01-12 07:47 -0800
Last post2016-02-11 07:39 -0800
Articles 20 on this page of 127 — 28 participants

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


Contents

  Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 07:47 -0800
    Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-12 16:25 +0000
      Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-12 10:45 -0600
      Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 08:46 -0800
        Re: Ruby/Forth challenge for WJ rickman <gnuarm@gmail.com> - 2016-01-12 11:57 -0500
          Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 09:22 -0800
            Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-01-12 21:04 -0800
              Re: Ruby/Forth challenge for WJ Ron Aaron <rambamist@gmail.com> - 2016-01-13 07:59 +0200
        Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-12 19:42 +0000
          Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-12 12:53 -0800
      Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-13 15:45 +0000
        Re: Ruby/Forth challenge for WJ rickman <gnuarm@gmail.com> - 2016-01-13 13:44 -0500
          Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-13 11:39 -0800
            Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-14 05:01 +0100
            Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-14 12:28 +0000
    Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 09:50 -0800
    Re: Ruby/Forth challenge for WJ Pablo Hugo Reda <pabloreda@gmail.com> - 2016-01-12 11:50 -0800
    Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 12:30 -0800
    Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 12:43 -0800
      Re: Ruby/Forth challenge for WJ stephen@mpeforth.com (Stephen Pelc) - 2016-01-12 21:01 +0000
      Re: Ruby/Forth challenge for WJ peter.m.falth@gmail.com - 2016-01-12 15:00 -0800
        Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-12 16:13 -0800
          Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-12 16:22 -0800
          Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-12 16:24 -0800
            Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-12 17:46 -0800
              Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-12 18:39 -0800
                Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-13 13:05 -0800
                  Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-14 04:33 +0100
                    Re: Ruby/Forth challenge for WJ m.a.m.hendrix@tue.nl - 2016-01-14 03:27 -0800
                      Re: Ruby/Forth challenge for WJ peter.m.falth@gmail.com - 2016-01-14 04:42 -0800
                      Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-14 13:03 +0000
                  Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-13 21:17 -0800
                    Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-01-13 21:44 -0800
                  Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-14 10:57 +0000
                    Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-14 12:20 -0800
                      Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-14 13:57 -0800
                        Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-14 14:22 -0800
                          Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-14 16:14 -0800
                          Re: Ruby/Forth challenge for WJ Melzzzzz <mel@zzzzz.com> - 2016-01-15 03:05 +0100
                        Re: Ruby/Forth challenge for WJ Waldek Hebisch <hebisch@antispam.uni.wroc.pl> - 2016-01-15 00:41 +0000
                      Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-15 16:22 +0000
                        Re: Ruby/Forth challenge for WJ mhx@iae.nl (Marcel Hendrix) - 2016-01-16 11:44 +0200
                          Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-16 04:49 -0800
                            Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-16 15:05 +0000
                              Re: Ruby/Forth challenge for WJ m.a.m.hendrix@tue.nl - 2016-01-18 03:26 -0800
                                Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-18 12:48 +0000
                                  Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-19 22:26 +0100
                                    Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-20 03:05 -0800
                                      Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-20 21:00 +0100
                                        Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-20 15:57 -0800
                                          Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-21 23:02 +0100
                                            Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-22 01:25 +0000
                                              Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-01-21 18:05 -0800
                                              Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-21 22:03 -0800
                                    Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-20 13:40 +0000
                              Re: Ruby/Forth challenge for WJ m.a.m.hendrix@tue.nl - 2016-01-18 03:55 -0800
                            Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-23 15:13 -0600
                              Re: Ruby/Forth challenge for WJ mhx@iae.nl - 2016-01-24 00:55 -0800
                                Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-25 04:48 -0600
                                  Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-25 12:39 +0000
                                    Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-25 08:05 -0600
                                      Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-25 16:40 +0000
                                  Re: Ruby/Forth challenge for WJ Mark Wills <markwills1970@gmail.com> - 2016-01-25 04:44 -0800
                                  Re: Ruby/Forth challenge for WJ stephen@mpeforth.com (Stephen Pelc) - 2016-01-25 14:01 +0000
                                    Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-25 08:08 -0600
                                      Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-25 11:56 -0600
                                        Re: Ruby/Forth challenge for WJ "Elizabeth D. Rather" <erather@forth.com> - 2016-01-25 11:12 -1000
                                          Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-26 03:33 -0600
                                          Re: Ruby/Forth challenge for WJ stephen@mpeforth.com (Stephen Pelc) - 2016-01-26 11:09 +0000
                                        Re: Ruby/Forth challenge for WJ stephen@mpeforth.com (Stephen Pelc) - 2016-01-26 11:06 +0000
                                          Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-26 07:45 -0600
                                            Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-26 16:46 +0000
                                              Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-26 11:16 -0600
                                                Object-oriented Forth (was: Ruby/Forth challenge for WJ) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-27 14:13 +0000
                                                  Re: Object-oriented Forth Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-27 10:33 -0600
                                                    Re: Object-oriented Forth hughaguilar96@gmail.com - 2016-01-27 08:45 -0800
                                                      Re: Object-oriented Forth Chris Curl <ccurl609@gmail.com> - 2016-01-27 09:14 -0800
                                                        Re: Object-oriented Forth hughaguilar96@gmail.com - 2016-01-29 21:57 -0800
                                                          Re: Object-oriented Forth Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-30 10:58 +0000
                                                          Re: Object-oriented Forth Chris Curl <ccurl609@gmail.com> - 2016-01-30 09:38 -0800
                                                            Re: Object-oriented Forth Coos Haak <chforth@hccnet.nl> - 2016-01-30 20:39 +0100
                                          Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-26 15:56 +0100
                                            Re: Ruby/Forth challenge for WJ stephen@mpeforth.com (Stephen Pelc) - 2016-01-26 20:46 +0000
                                    Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-25 22:27 +0100
                                      Re: Ruby/Forth challenge for WJ Roelf Toxopeus <rt4all@notthis.hetnet.nl> - 2016-01-28 14:20 +0100
                                      Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-28 08:06 -0600
                                        Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-28 16:14 +0100
                                          Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-28 10:32 -0600
                                            Re: Ruby/Forth challenge for WJ anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-28 17:26 +0000
                                              Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-28 12:13 -0600
                                          Re: Ruby/Forth challenge for WJ Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-29 11:07 +0000
                                            Re: Ruby/Forth challenge for WJ Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-29 21:18 +0100
                          Re: Ruby/Forth challenge for WJ Tessa Bonting <tessa.bonting@gmail.com> - 2016-01-16 06:24 -0800
            Re: Ruby/Forth challenge for WJ Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-13 05:21 -0500
              Re: Ruby/Forth challenge for WJ Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-13 05:36 -0500
              Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-13 10:33 -0800
                Re: Ruby/Forth challenge for WJ Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-14 01:37 -0500
    Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 13:45 -0800
    Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 13:55 -0800
      Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-12 14:34 -0800
      Re: Ruby/Forth challenge for WJ rickman <gnuarm@gmail.com> - 2016-01-12 19:00 -0500
        Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 16:49 -0800
          Re: Ruby/Forth challenge for WJ rickman <gnuarm@gmail.com> - 2016-01-12 22:18 -0500
    Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-01-12 14:31 -0800
      Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-12 16:05 -0800
    Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-01-13 07:58 +0000
      Re: Ruby/Forth challenge for WJ Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-13 05:17 -0500
        Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-13 12:36 -0800
          Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-13 12:53 -0800
          Re: Ruby/Forth challenge for WJ Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-14 06:50 -0600
      Re: Ruby/Forth challenge for WJ Julian Fondren <julian.fondren@gmail.com> - 2016-01-13 05:36 -0800
      Re: Ruby/Forth challenge for WJ lehs <skydda.barnen@gmail.com> - 2016-01-13 11:59 -0800
      Re: Ruby/Forth challenge for WJ Chris Curl <ccurl609@gmail.com> - 2016-01-21 21:08 -0800
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-09 13:36 +0000
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-09 13:48 +0000
        Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-02-09 12:02 -0800
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-09 13:58 +0000
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-09 14:30 +0000
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-14 15:35 +0000
        Re: Ruby/Forth challenge for WJ franck.bensusan@gmail.com - 2016-02-14 08:50 -0800
          Re: Ruby/Forth challenge for WJ Julian Fondren <julian.fondren@gmail.com> - 2016-02-14 20:09 -0800
            Re: Ruby/Forth challenge for WJ hughaguilar96@gmail.com - 2016-02-15 08:52 -0800
      Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-02-14 21:31 +0000
    Re: Ruby/Forth challenge for WJ "WJ" <w_a_x_man@yahoo.com> - 2016-01-14 22:49 +0000
      Re: Ruby/Forth challenge for WJ Paul Rubin <no.email@nospam.invalid> - 2016-01-14 15:31 -0800
        Re: Ruby/Forth challenge for WJ Melzzzzz <mel@zzzzz.com> - 2016-01-15 06:55 +0100
    Re: Ruby/Forth challenge for WJ djc <ciesinger@gmx.net> - 2016-02-11 07:39 -0800

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


#45209 — Re: Object-oriented Forth

FromCoos Haak <chforth@hccnet.nl>
Date2016-01-30 20:39 +0100
SubjectRe: Object-oriented Forth
Message-ID<fo3dorfgplyv.1j1wm8841cufh$.dlg@40tude.net>
In reply to#45203
Op Sat, 30 Jan 2016 09:38:32 -0800 (PST) schreef Chris Curl:

<snip>
> Thanks. I might be missing something though, because it seems to me that in Forth, 
> assuming you are using a stack (either the main stack or an auxiliary stack) for 
> local variables, this ability is built in, simply because the calling word's local 
> variables are on the stack when the child word is called. The called word just needs
> to know where to look. If "quotations" is just a way to refer to such an approach,
> then I think I get it.

Locals cannot be on the data stack, what will happen someone used SWAP ?
Locals must be on the return stack or a dedicatet locals stack.

groet Coos

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


#45088

FromBernd Paysan <bernd.paysan@gmx.de>
Date2016-01-26 15:56 +0100
Message-ID<n88198$dcg$1@dont-email.me>
In reply to#45083
Stephen Pelc wrote:
> And perhaps you would let those who want to standardise an
> old-fashioned OOP do so in peace.

The problem of the 20 years old Forth OOP extensions is that they have too 
little overlap in the features to be useful outside of the box they have 
been made for.  These 20+ OOP systems are *not* the same, rather the 
contrarly: They explore all different parts of the OOP space, IIRC, we have 
found at least 6 orthogonal decisions, which means that there is room for 64 
different and mutually incompatible OOP systems.  The discussion with Klaus 
was very symptomatic with a lots of "I don't need this", just because he 
never had thought of this particular possible feature.  This was a core 
concept of OOP according to the literature...

Andrew's idea was to provide building blocks so that people can use those to 
create their special-purpose OOP system, or extend their special purpose OOP 
system by using those building blocks to make them more generalized.

My experience with proposing such building blocks (like the current object + 
instance and method invocation based on it, or the recognizer) is that the 
"I don't need this" mentality is still very strong.  Especially, since the 
strongest "I don't need this" came from exactly the person which needs it 
most, because he has cluttered his outer interpreter with tons of hooks, 
because he had needed recognizers 20 years ago, but didn't realize it.

Forth design says you should only solve the problem at hand, and not 
overgeneralize.  So "I don't need this" as answer is perfectly fine in the 
Forth world; the consequence however is that this particular aspect is not 
going to be standardized.

So whoever calls for a standard on OOP shall stop telling other people that 
he doesn't need this or that, or shut up with his request for 
standardization.  The second option is perfectly fine, we probably don't 
need an OOP standard.  We too much strive for simplicity and lightweight 
solutions that are only fit for a particular purpose, but we then really 
should accept that they are of limited reusability, and therefore not good 
enough for everybody.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ*
http://bernd-paysan.de/

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


#45096

Fromstephen@mpeforth.com (Stephen Pelc)
Date2016-01-26 20:46 +0000
Message-ID<56a7da71.1184619893@news.eternal-september.org>
In reply to#45088
On Tue, 26 Jan 2016 15:56:15 +0100, Bernd Paysan <bernd.paysan@gmx.de>
wrote:

>My experience with proposing such building blocks (like the current object + 
>instance and method invocation based on it, or the recognizer) is that the 
>"I don't need this" mentality is still very strong.  Especially, since the 
>strongest "I don't need this" came from exactly the person which needs it 
>most, because he has cluttered his outer interpreter with tons of hooks, 
>because he had needed recognizers 20 years ago, but didn't realize it.

You have not understood my objections to standardising recognisers
*now*. Please let me speak for myself.

Stephen

-- 
Stephen Pelc, stephenXXX@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

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


#45077

FromBernd Paysan <bernd.paysan@gmx.de>
Date2016-01-25 22:27 +0100
Message-ID<n863qn$7m4$1@dont-email.me>
In reply to#45066
Stephen Pelc wrote:

> On Mon, 25 Jan 2016 04:48:12 -0600, Andrew Haley
> <andrew29@littlepinkcloud.invalid> wrote:
> 
>>And a final conclusion: we still don't have any kind of standard
>>concurrency mechanisms in Forth.  Sigh.  Some kind of load-balancing
>>system like Cilk Plus would be a nice thing to have, and wouldn't be
>>all that hard to use.
> 
> Well, propose a basic one for single CPU use. Then you can have EXT
> for multi-core. Hmm, you still still owe us the OOP proposal you
> made some years ago.

Gforth uses words derived from the "de facto standard" cooperative Forth 
multitasker to define pthread-based multithreading, has semaphores to avoid 
conflicts, and events for inter-task communication.

That's a level below Cilk Plus with spawn+sync, but you can easily define it 
by creating a worker thread for every core you have, and then have the 
following events:

--------------------------cilk.fs--------------------------
require unix/pthread.fs

s" grep siblings /proc/cpuinfo | head -1 | cut -f2 -d:" r/o open-pipe throw
include-file Value cores

Variable sync#
Variable workers
User invoker

: worker@ ( -- worker )
    BEGIN  workers $@ IF @ workers 0 cell $del ELSE drop 0 THEN
    dup 0= WHILE drop stop REPEAT ;

event: ->sync ( task -- )
    { w^ task } task cell workers $+! -1 sync# +! ;
: +worker ( task -- )
    <event up@ elit, ->sync event> ;

event: ->spawn ( xt task -- )
    invoker ! execute clearstack ;
: worker-thread ( -- )
    stacksize4 newtask4 activate [ up@ ]l invoker !
    BEGIN  invoker @ +worker stop  AGAIN ;

cores 1 max 0 [DO] worker-thread [LOOP] 1 ms sync# off

: sync ( -- )
    \G wait for all spawned tasks to complete
    BEGIN  sync# @  0> WHILE  stop  REPEAT ;
: spawn-rest ( xt -- )
    elit, up@ elit, ->spawn worker@ event> 1 sync# +! ;
: spawn ( xt -- )
    \G wait for a worker to become free, and spawn xt there
    <event spawn-rest  ;
: spawn1 ( n xt -- )
    \G wait for a worker to become free, and spawn xt there, with one 
argument
    <event swap elit, spawn-rest ;
: spawn2 ( n1 n2 xt -- )
    \G wait for a worker to become free, and spawn xt there, with two 
arguments
    <event >r swap elit, elit, r> spawn-rest ;

0 warnings !@
: bye ( -- )
    sync cores 0 ?DO worker@ kill LOOP 1 ms bye ;
warnings !
--------------------------cilk.fs--------------------------

with WORKER@ choosing the next free worker (if any); blocking if none is 
ready (it will be woken up by the next ->sync event).

STOP contains the event interpreter, which is essentially a token-threaded 
Forth for all those words defined by event:.

Assumption: Main thread spawns and syncs, helper thread just perform 
workload; therefore sync# doesn't need to be a user variable, and workers 
doesn't need a semaphore to protect it.

The single-thread implementation is trivial:

: sync ( -- ) ;
: spawn ( xt -- ) execute ; \ spawn1 + 2 same definition

That was a remarkable quick exercise.  Results probably should be returned 
by storing them into a passed address.  The event mechanism can be used to 
pass arguments when spawning and return values at completion.

If you allow recursive spawning, sync should add the current thread as 
worker, and remove it after sync is completed.

Test:

: test ( n -- ) ms ." test done" cr ;  ok                           
: tests ( n -- ) 0 DO  i 100 * ['] test spawn1  LOOP
  sync ." sync done" ;
16 tests

I'll probably experiment with this a bit more; it looks like spawn should be 
separated in a pass-argument part, and what's now called spawn-rest.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ*
http://bernd-paysan.de/

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


#45150

FromRoelf Toxopeus <rt4all@notthis.hetnet.nl>
Date2016-01-28 14:20 +0100
Message-ID<56aa15af$0$12326$e4fe514c@textnews.kpn.nl>
In reply to#45077
On 25/01/16 22:27, Bernd Paysan wrote:
> Stephen Pelc wrote:
>
>> On Mon, 25 Jan 2016 04:48:12 -0600, Andrew Haley
>> <andrew29@littlepinkcloud.invalid> wrote:
>>
>>> And a final conclusion: we still don't have any kind of standard
>>> concurrency mechanisms in Forth.  Sigh.  Some kind of load-balancing
>>> system like Cilk Plus would be a nice thing to have, and wouldn't be
>>> all that hard to use.
>>
>> Well, propose a basic one for single CPU use. Then you can have EXT
>> for multi-core. Hmm, you still still owe us the OOP proposal you
>> made some years ago.
>
> Gforth uses words derived from the "de facto standard" cooperative Forth
> multitasker to define pthread-based multithreading, has semaphores to avoid
> conflicts, and events for inter-task communication.
>
> That's a level below Cilk Plus with spawn+sync, but you can easily define it
> by creating a worker thread for every core you have, and then have the
> following events:
>
> --------------------------cilk.fs--------------------------
> require unix/pthread.fs
>
> s" grep siblings /proc/cpuinfo | head -1 | cut -f2 -d:" r/o open-pipe throw
> include-file Value cores
>
> Variable sync#
> Variable workers
> User invoker
>
> : worker@ ( -- worker )
>      BEGIN  workers $@ IF @ workers 0 cell $del ELSE drop 0 THEN
>      dup 0= WHILE drop stop REPEAT ;
>
> event: ->sync ( task -- )
>      { w^ task } task cell workers $+! -1 sync# +! ;
> : +worker ( task -- )
>      <event up@ elit, ->sync event> ;
>
> event: ->spawn ( xt task -- )
>      invoker ! execute clearstack ;
> : worker-thread ( -- )
>      stacksize4 newtask4 activate [ up@ ]l invoker !
>      BEGIN  invoker @ +worker stop  AGAIN ;
>
> cores 1 max 0 [DO] worker-thread [LOOP] 1 ms sync# off
>
> : sync ( -- )
>      \G wait for all spawned tasks to complete
>      BEGIN  sync# @  0> WHILE  stop  REPEAT ;
> : spawn-rest ( xt -- )
>      elit, up@ elit, ->spawn worker@ event> 1 sync# +! ;
> : spawn ( xt -- )
>      \G wait for a worker to become free, and spawn xt there
>      <event spawn-rest  ;
> : spawn1 ( n xt -- )
>      \G wait for a worker to become free, and spawn xt there, with one
> argument
>      <event swap elit, spawn-rest ;
> : spawn2 ( n1 n2 xt -- )
>      \G wait for a worker to become free, and spawn xt there, with two
> arguments
>      <event >r swap elit, elit, r> spawn-rest ;
>
> 0 warnings !@
> : bye ( -- )
>      sync cores 0 ?DO worker@ kill LOOP 1 ms bye ;
> warnings !
> --------------------------cilk.fs--------------------------
>
> with WORKER@ choosing the next free worker (if any); blocking if none is
> ready (it will be woken up by the next ->sync event).
>
> STOP contains the event interpreter, which is essentially a token-threaded
> Forth for all those words defined by event:.
>
> Assumption: Main thread spawns and syncs, helper thread just perform
> workload; therefore sync# doesn't need to be a user variable, and workers
> doesn't need a semaphore to protect it.
>
> The single-thread implementation is trivial:
>
> : sync ( -- ) ;
> : spawn ( xt -- ) execute ; \ spawn1 + 2 same definition
>
> That was a remarkable quick exercise.  Results probably should be returned
> by storing them into a passed address.  The event mechanism can be used to
> pass arguments when spawning and return values at completion.
>
> If you allow recursive spawning, sync should add the current thread as
> worker, and remove it after sync is completed.
>
> Test:
>
> : test ( n -- ) ms ." test done" cr ;  ok
> : tests ( n -- ) 0 DO  i 100 * ['] test spawn1  LOOP
>    sync ." sync done" ;
> 16 tests
>
> I'll probably experiment with this a bit more; it looks like spawn should be
> separated in a pass-argument part, and what's now called spawn-rest.
>

Neat!

BTW I wonder if it occurred to you, or Andrew Haley for that matter, 
that some Forth users already have a SPAWN in usage without any 
knowledge of some existing non-Forth library.

For instance my current version of SPAWN is used for things like:

FRAMEWORK Carbon.framework
FUNCTION: SysBeep ( n -- ret )

: BEEP ( -- )   0 SysBeep DROP ;

: BEEPER ( -- )   20 CHOOSE 1+ 0 DO 180 800 ALEA MS BEEP LOOP ;

: BEEP+ ( -- )   250 750 ALEA MS ['] BEEPER SPAWN ;

: BB ( -- ) BEGIN TOSS IF BEEP+ THEN KEY? UNTIL ;

Sonology way of testing random number generator(s) ;-)

I don't have SYNC and this version doesn't get a passed in parameter and 
is not depending on the number of available cores.
There are a 1001 ways of doing this. Lots of variations. Depends on what 
you need. I would always redefine SPAWN to the situation at hand.
It's such a useful name for many (similar) things.

As a non-english speaker, I first encountered the word and concept of 
SPAWN in SuperCollider https://supercollider.github.io in the 1990's. 
Found it a great catchy name to use in Forth for similar actions.
First implemented as anonymous, headless tasks (with garbage collector) 
in MacForth's coop multitasker, on single core PPC. Later pthreads, then 
threadpools with workers snoozing and lastly Grand Central Dispatch on 
the Mac for SwiftForth, VFX and iForth, on multicore MacIntels.

To deliberately run a word on a separate core from the main thread, I 
use the names FORK JOIN (and CONTINUE) as proposed by Andrew Haley a few 
years ago. Similar to DFW's PAR END-PAR.


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


#45153

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2016-01-28 08:06 -0600
Message-ID<ENadncvB9K_WvTfLnZ2dnUU7-aOdnZ2d@supernews.com>
In reply to#45077
Bernd Paysan <bernd.paysan@gmx.de> wrote:
> 
> Assumption: Main thread spawns and syncs, helper thread just perform 
> workload; therefore sync# doesn't need to be a user variable, and workers 
> doesn't need a semaphore to protect it.
> 
> The single-thread implementation is trivial:
> 
> : sync ( -- ) ;
> : spawn ( xt -- ) execute ; \ spawn1 + 2 same definition
> 
> That was a remarkable quick exercise.

Great, that's neat, but it's not work stealing.  SYNC should only wait
for a subset of tasks, not the ones spawned by other threads, and it's
important not just to spin waiting for other threads if there is still
work to be done.

> I'll probably experiment with this a bit more; it looks like spawn
> should be separated in a pass-argument part, and what's now called
> spawn-rest.

The real algorithm is more sophisticated than you're giving it credit
for.  It's described here:

https://en.wikipedia.org/wiki/Work_stealing

The lock-free algorithm for grabbing tasks to be done is very
important to doing this efficiently.  And it's very important to use a
double-ended queue.

Andrew.

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


#45157

FromBernd Paysan <bernd.paysan@gmx.de>
Date2016-01-28 16:14 +0100
Message-ID<n8db47$mr8$1@dont-email.me>
In reply to#45153
Andrew Haley wrote:

> Bernd Paysan <bernd.paysan@gmx.de> wrote:
>> 
>> Assumption: Main thread spawns and syncs, helper thread just perform
>> workload; therefore sync# doesn't need to be a user variable, and workers
>> doesn't need a semaphore to protect it.
>> 
>> The single-thread implementation is trivial:
>> 
>> : sync ( -- ) ;
>> : spawn ( xt -- ) execute ; \ spawn1 + 2 same definition
>> 
>> That was a remarkable quick exercise.
> 
> Great, that's neat, but it's not work stealing.  SYNC should only wait
> for a subset of tasks, not the ones spawned by other threads, and it's
> important not just to spin waiting for other threads if there is still
> work to be done.

This first attempt works only for one spawner; I'm going to extend this.  
SYNC# will then become a user variable, so each thread is only counting the 
own spawns.

>> I'll probably experiment with this a bit more; it looks like spawn
>> should be separated in a pass-argument part, and what's now called
>> spawn-rest.
> 
> The real algorithm is more sophisticated than you're giving it credit
> for.  It's described here:
> 
> https://en.wikipedia.org/wiki/Work_stealing
> 
> The lock-free algorithm for grabbing tasks to be done is very
> important to doing this efficiently.  And it's very important to use a
> double-ended queue.

The IPC for the events (which need to be atomic) under Linux is so damn'd 
expensive (it needs to wake sleeping tasks, doing it generically costs about 
10k instructions) that I need to look at doing that cheaper, too.  As long 
as the task still is active, you don't have to wake it up, it will look into 
the event queue, anyways.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ*
http://bernd-paysan.de/

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


#45164

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2016-01-28 10:32 -0600
Message-ID<Ud6dnb6lA7kQ3zfLnZ2dnUU78IGdnZ2d@supernews.com>
In reply to#45157
Bernd Paysan <bernd.paysan@gmx.de> wrote:
> Andrew Haley wrote:
> 
>> Bernd Paysan <bernd.paysan@gmx.de> wrote:
>> 
>> https://en.wikipedia.org/wiki/Work_stealing
>> 
>> The lock-free algorithm for grabbing tasks to be done is very
>> important to doing this efficiently.  And it's very important to use a
>> double-ended queue.
> 
> The IPC for the events (which need to be atomic) under Linux is so
> damn'd expensive (it needs to wake sleeping tasks, doing it
> generically costs about 10k instructions) that I need to look at
> doing that cheaper, too.  As long as the task still is active, you
> don't have to wake it up, it will look into the event queue,
> anyways.

Indeed, and the queues (note that each worker has its own) have to be
double-ended because local jobs are pulled from one end, and remote
jobs from the other, balancing load and minimizing overhead.

Andrew.

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


#45169

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-01-28 17:26 +0000
Message-ID<2016Jan28.182643@mips.complang.tuwien.ac.at>
In reply to#45164
Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>Indeed, and the queues (note that each worker has its own) have to be
>double-ended because local jobs are pulled from one end, and remote
>jobs from the other, balancing load and minimizing overhead.

Not sure how that balances load more than taking the jobs from the
same end, but, concerning overhead, my guess is that this reduces
cache ping-ponging.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2015: http://www.rigwit.co.uk/EuroForth2015/

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


#45171

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2016-01-28 12:13 -0600
Message-ID<CoudnSB-6vuxxzfLnZ2dnUU78L2dnZ2d@supernews.com>
In reply to#45169
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>>Indeed, and the queues (note that each worker has its own) have to be
>>double-ended because local jobs are pulled from one end, and remote
>>jobs from the other, balancing load and minimizing overhead.
> 
> Not sure how that balances load more than taking the jobs from the
> same end, but, concerning overhead, my guess is that this reduces
> cache ping-ponging.

Two things: except for the last item, a worker can pull and push tasks
on its own queue with little or no synchronization.  Remote workers
must use a CAS.  Also, small tasks are usually at the bottom end of
the queue and large tasks are at the top, and remote workers prefer to
steal large tasks.  This minimizes communication overhead.

But all of this is online, particularly [1]

Andrew.

[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.170.1097&rep=rep1&type=pdf

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


#45178

FromAlbert van der Horst <albert@spenarnc.xs4all.nl>
Date2016-01-29 11:07 +0000
Message-ID<56ab47e4$0$23826$e4fe514c@news.xs4all.nl>
In reply to#45157
Bernd Paysan <bernd.paysan@gmx.de> writes:

>Andrew Haley wrote:

>> Bernd Paysan <bernd.paysan@gmx.de> wrote:
>>>
>>> Assumption: Main thread spawns and syncs, helper thread just perform
>>> workload; therefore sync# doesn't need to be a user variable, and workers
>>> doesn't need a semaphore to protect it.
>>>
>>> The single-thread implementation is trivial:
>>>
>>> : sync ( -- ) ;
>>> : spawn ( xt -- ) execute ; \ spawn1 + 2 same definition
>>>
>>> That was a remarkable quick exercise.
>>
>> Great, that's neat, but it's not work stealing.  SYNC should only wait
>> for a subset of tasks, not the ones spawned by other threads, and it's
>> important not just to spin waiting for other threads if there is still
>> work to be done.

>This first attempt works only for one spawner; I'm going to extend this.
>SYNC# will then become a user variable, so each thread is only counting the
>own spawns.

>>> I'll probably experiment with this a bit more; it looks like spawn
>>> should be separated in a pass-argument part, and what's now called
>>> spawn-rest.
>>
>> The real algorithm is more sophisticated than you're giving it credit
>> for.  It's described here:
>>
>> https://en.wikipedia.org/wiki/Work_stealing
>>
>> The lock-free algorithm for grabbing tasks to be done is very
>> important to doing this efficiently.  And it's very important to use a
>> double-ended queue.

>The IPC for the events (which need to be atomic) under Linux is so damn'd
>expensive (it needs to wake sleeping tasks, doing it generically costs about
>10k instructions) that I need to look at doing that cheaper, too.  As long
>as the task still is active, you don't have to wake it up, it will look into
>the event queue, anyways.

To be specific, if two task communicate through a classic pipe,
a blocked read will set you back 10 K instructions?
(That's not good for a parallel prime number sieve ;-) )
>--
>Bernd Paysan
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#45185

FromBernd Paysan <bernd.paysan@gmx.de>
Date2016-01-29 21:18 +0100
Message-ID<n8gh8o$o8p$1@dont-email.me>
In reply to#45178
Albert van der Horst wrote:
> To be specific, if two task communicate through a classic pipe,
> a blocked read will set you back 10 K instructions?
> (That's not good for a parallel prime number sieve ;-) )

Yes, any other IPC for waking up another core is about as expensive.  A Core 
i7 with Linux is clearly not a GA144.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ*
http://bernd-paysan.de/

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


#44909

FromTessa Bonting <tessa.bonting@gmail.com>
Date2016-01-16 06:24 -0800
Message-ID<9943b371-987c-4115-bd11-791ba867d30b@googlegroups.com>
In reply to#44905
Op zaterdag 16 januari 2016 11:45:00 UTC+1 schreef Marcel Hendrix:
> anton@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: Ruby/Forth challenge 
> \ FORTH> do-tests
> \ count1  : 0.072 seconds elapsed.
> \ count2  : 0.280 seconds elapsed.
> \ count3  : 0.521 seconds elapsed.
> \ count4  : 0.486 seconds elapsed.
> \ count5  : 0.494 seconds elapsed.
> \ count6  : 0.497 seconds elapsed.
> \ count7  : 0.523 seconds elapsed.
> \ count8a : 0.421 seconds elapsed.
> \ count8b : 0.484 seconds elapsed.
> \ count8c : 0.494 seconds elapsed.
> \ count8d : 0.139 seconds elapsed.
> \ count9  : 0.070 seconds elapsed.
> \ count10 : 0.056 seconds elapsed.

The branch prediction in a tide loop cost more
cycles since the prediction is started with a paralel
set of the registers and takes some cycles to see that 
it predicted it wright.
Now in the tide loop a second prediction is started
before the first is handled completely so a second
set of the registers is used and the predicted 
jump is run.
Now is it so that the pentium would only allow one
prediction at a time, so there would be no difference
between a tide or a large loop.
From the pentium4 that changed since it introduced
a jump prediction handling code buffer of about 8
jump long.
So the jump prediction code buffer simply overflows
as the result takes some time to chech that the pre-
dection was right.
As a result the next jump would have to wait for the 
buffer to have room for a start of a next code part
to be handled and that gives a penalty of about 17 
cycles.
Newer precessor have a bigger prediction handling
buffer but that also would overflow at some time.
Putting extra instruction between the begin and 
the until fills the pipe lines (yes there are stil
pipi lines and a lot of them) and gives the branch
prediction the time to finish without the delays.

Allso the out of order execution with the paralel 
execution of one 4 uops instruction with 3 1 uops
instructions gives the somewhat stranch going faster
as more NOP's are inserted, with the optimum of the 
time needed for the branch prediction cycles, and 
from there it just takes time to handle the extra 
NOP's.

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


#44819

FromRod Pemberton <NoHaveNotOne@bcczxcfre.cmm>
Date2016-01-13 05:21 -0500
Message-ID<20160113052158.07176e0d@_>
In reply to#44808
On Tue, 12 Jan 2016 16:24:42 -0800
Paul Rubin <no.email@nospam.invalid> wrote:

> Paul Rubin <no.email@nospam.invalid> writes:

> >> with my 32 bit native code generating forth I get 983 ms on the
> >> same laptop  
> > Interestingly, your 32 bit Forth is beating 64 bit C++ by a wide
> > margin, even with C++ running on a considerably faster machine
> > (i7-3770).  
> 
> Oh never mind, with optimization off and subscript checking on, I was
> getting about 1 sec (GCC 4.7.2).  With optimization -O3 and unsafe
> subscripts, I get 141 ms.  This is just for the counting part, not the
> random initialization, which depends considerably on which PRNG you
> use. The subscript checking actually only makes a tiny difference.
> 
> ================================================================
> 
> #include <iostream>
> #include <random>
> #include <array>
> #include <cstdint>
> #include <chrono>
> 
> const int Bufsize = 1<<28;
> std::array<std::uint8_t, Bufsize+3> buf;
> 
> void init_array()
> {
>   std::minstd_rand rd;
>   for (int i = 0; i < buf.size(); i += 3)
>     {
>       int r = rd();
>       buf[i] = r&0xff;
>       r >>= 8; 
>       buf[i+1] = r&0xff;
>       r >>= 8; 
>       buf[i+2] = r&0xff;
>     }
>  }
> 
> int main(int argc, char **argv) {
>   auto t0 = std::chrono::high_resolution_clock::now();
>   init_array();
>   auto t1 = std::chrono::high_resolution_clock::now();
> 
>   static std::array<std::uint32_t, 256> counts;
>   for (uint8_t b: buf) {
>     ++counts[b];
>   }
>   auto t2 = std::chrono::high_resolution_clock::now();
>   std::chrono::duration<double> d1 = t1 - t0;
>   std::chrono::duration<double> d2 = t2 - t1;
>   std::cout << d1.count () << " " << d2.count() << std::endl;
>   return 0;  
> }

Shouldn't r be unsigned?

Why didn't you use 'unsigned char' for buf?

I'm not familiar with C++, but I suspect 'i<buf.size()'
returns 'Bufsize+3'.  Don't you want 'Bufsize' returned?

I used to use 'char **argv' instead of 'char *argv[]' for
many years also.  It's not technically valid for C,
perhaps it is for C++.  You didn't use them.  So, 'void'.


Are the results of your app in seconds?
 (g++ -std=c++11 -O2)

# ./pr
0.660104 0.436355

# ./pr
0.669993 0.436285

# ./pr
0.659609 0.43627

The results are going to be processor speed dependent.

If I attempt to convert your C++ code to ANSI C,
knowing very little about C++, the times come out
rather different:

# ./pr
1.016804   0.000000

# ./pr
0.926480   0.000000

# ./pr
1.002100   0.000000

All of the time is front loaded.

I would expect the times to be somewhat similar
but, I had to use one non-ANSI, Linux time function
which I've never used before.

I.e., if the counts aren't taking much time in C,
I'd wonder why C++ took so long.  Or, why C++ was
so much faster with the array initialization than
C was.

Perhaps, I made a mistake porting somewhere.  Or,
maybe there is some difference with the values
returned by the time functions?  Maybe, -O2 optimized
away the unused counts loop for C, but kept it for
C++?  Well, take a look or run it, if interested:

/* LINUX only, almost ANSI C */
/* for 32-bit or 64-bit */

#include <stdio.h> /* printf */
#include <stdlib.h> /* srand rand */
#include <time.h> /* time clock_gettime */

#define CNT 256
#define BUF 268435456UL
#define BIL 1000000000UL

unsigned char buf[BUF+3];

void init_array(void)
{
  int i,r;

  srand(time(0));

  for(i=0;i<BUF;i+=3)
  {
    r=rand();
    buf[i]=r&0xff;
    r>>=8;
    buf[i+1]=r&0xff;
    r>>=8;
    buf[i+2]=r&0xff;
  }
}

int main(void)
{
  unsigned int counts[CNT];
  unsigned long i;
  struct timespec tim0,tim1,tim2;
  unsigned long long t0,t1,t2;

  /* memset */
  for(i=0;i<CNT;i++);
    counts[i]=0;

  clock_gettime(CLOCK_MONOTONIC,&tim0);
  init_array();
  clock_gettime(CLOCK_MONOTONIC,&tim1);

  for(i=0;i<BUF;i++)
    counts[buf[i]]++;

  clock_gettime(CLOCK_MONOTONIC,&tim2);

  t0=tim0.tv_sec*BIL+tim0.tv_nsec;
  t1=tim1.tv_sec*BIL+tim1.tv_nsec;
  t2=tim2.tv_sec*BIL+tim2.tv_nsec;

  printf("%10.6f %10.6f\n",((double)(t1-t0))/BIL,((double)(t2-t1))/BIL);

return(0);
}


Rod Pemberton

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


#44820

FromRod Pemberton <NoHaveNotOne@bcczxcfre.cmm>
Date2016-01-13 05:36 -0500
Message-ID<20160113053654.65ba685a@_>
In reply to#44819
On Wed, 13 Jan 2016 05:21:58 -0500
Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> wrote:

> Why didn't you use 'unsigned char' for buf?

Ignore that.  It's a uint8_t.


RP

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


#44831

FromPaul Rubin <no.email@nospam.invalid>
Date2016-01-13 10:33 -0800
Message-ID<8760yxuy6a.fsf@nightsong.com>
In reply to#44819
Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> writes:
> Shouldn't r be unsigned?

Hmm, that would have been cleaner (actually uint_fast32_t) but int is ok
since the numbers from minstd_rand are always positive.  Also I'm only
taking the lower 24 bits.

> I'm not familiar with C++, but I suspect 'i<buf.size()'
> returns 'Bufsize+3'.  Don't you want 'Bufsize' returned?

Whoops!  Nice catch.  buf.size() was left over from a revision where I
was taking just 1 byte from each random number.

> I used to use 'char **argv' instead of 'char *argv[]' for
> many years also.  It's not technically valid for C,
> perhaps it is for C++.  You didn't use them.  So, 'void'.

Per  http://en.cppreference.com/w/cpp/language/main_function :
    The names argc and argv are arbitrary, as well as the representation
    of the types of the parameters: int main(int ac, char** av) is
    equally valid.
Maybe I should check Stroustrup's book though.

> Are the results of your app in seconds?
>  (g++ -std=c++11 -O2)
> # ./pr
> 0.660104 0.436355

I get: 0.382123 0.141022  (GCC 4.7.2 x86-64, i7-3770 3.4 GHz with -O2)
       0.443481 0.140997 with -O3
This is with the Bufsize fix and also replaced buf[i] with buf.at(i)
etc.  (That range-checks the subscript and causes almost no slowdown).
Interesting that -O3 does the initialization a little slower than -O2.

> # ./pr
> 1.016804   0.000000

The slower initialization is probably because minstd_rand is the C++
minimal standard RNG which is rather crappy but very fast.  The C one is
probably slower.  The 0.00000 is because the code is being optimized
away (see below).

> I.e., if the counts aren't taking much time in C

If it's really looking at 256M bytes then at 1 cycle per byte that's
around 0.1s at 2.5 GHz.  I don't think it can do much better than that.

I put printf("%d\n", counts[23]) at the end of your C version, and that
gave:

  0.673343   0.141221

it took 0.000000 without the extra print because the compiler saw that
counts (a local array in your version) was unused after being set.  The
C++ version had counts as a global, so my guess is the compiler presumed
that some other module might use it.

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


#44861

FromRod Pemberton <NoHaveNotOne@bcczxcfre.cmm>
Date2016-01-14 01:37 -0500
Message-ID<20160114013746.71f8991c@_>
In reply to#44831
On Wed, 13 Jan 2016 10:33:33 -0800
Paul Rubin <no.email@nospam.invalid> wrote:

> I put printf("%d\n", counts[23]) at the end of your C version, and
> that gave:
> 
>   0.673343   0.141221
> 
> it took 0.000000 without the extra print because the compiler saw that
> counts (a local array in your version) was unused after being set.
> The C++ version had counts as a global, so my guess is the compiler
> presumed that some other module might use it.

So, a few results without the optimized away loop:

 1.006349   0.398377
 1.035722   0.373584
 1.026238   0.368511
 0.964631   0.400756

Restructuring init_array() to not use shifts, but using
a pointer to char for direct byte reads, didn't seem to
help any.  Results hovered around the same values.

Maybe, computing a long-term result would slightly favor
one method over the other.  I didn't compare source via
gcc -S.  One is likely to produce fewer instructions.

I also considered calling rand() more frequently to
eliminate shifts, but I didn't test that.  I presumed
that rand() takes longer than the shifts.

FYI, those results are for:

3.2Ghz AMD Phenom II X2 555 (dual core)
64-bit VLocity Linux (VectorLinux)
GCC 4.7.2


Rod Pemberton

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


#44796

FromChris Curl <ccurl609@gmail.com>
Date2016-01-12 13:45 -0800
Message-ID<10f5274e-7f92-4ff1-a653-6d22fe076170@googlegroups.com>
In reply to#44782
Update: about 890 MS on SP-Forth.

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


#44797

FromChris Curl <ccurl609@gmail.com>
Date2016-01-12 13:55 -0800
Message-ID<65ba1513-cfa4-4ebe-9583-4729f4b0815a@googlegroups.com>
In reply to#44782
OK ... let's see how fast WJ's Ruby implementation runs.

Since Ruby is so much better than the "toy" language Forth, Ruby can do the same thing be much faster than 600ms, right?

WJ, the ball is in your court.

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


#44800

FromPaul Rubin <no.email@nospam.invalid>
Date2016-01-12 14:34 -0800
Message-ID<87y4bumnpp.fsf@jester.gateway.pace.com>
In reply to#44797
Chris Curl <ccurl609@gmail.com> writes:
> Since Ruby is so much better than the "toy" language Forth, Ruby can
> do the same thing be much faster than 600ms, right?

Just for laughs, I tried it in Python for 1MB instead of 256MB.  The
random initialization phase took 0.743 sec and the counting phase took
0.009 sec, scaling to about 23 sec for counting 256MB.  The random
initialization was pretty inefficient so I wouldn't count it despite not
seeing an obvious faster way.  The counting phase was the quickest
obvious way I could think of offhand, though maybe there is something
better.  The code is:

    from random import randrange
    import time
    import array
    import itertools

    def main():
        t0 = time.time()
        vec = bytearray(itertools.islice(
            iter(lambda: randrange(0,255), None),
            2**20
        )
        )
        t1 = time.time()
        u = array.array('i',[0]*256)
        for c in vec:
            u[c] += 1
        t2 = time.time()
        print t1-t0, t2-t1

    main()

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


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

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


csiph-web