Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Simpe Gwydion question

0 views
Skip to first unread message

Waldek Hebisch

unread,
Jul 10, 2002, 11:24:15 AM7/10/02
to
I just tried to write a simple dylan program. And I have the
following questions (they should be answerd in any tutorial
but I was unable to to find the answers):
-- How one prints a floating point number. I was able
to find examples of format, but only for integers
-- How one conwerts between numbers and strings (both integers
and floating point)
-- How one declares an array of doubles. Currently I use generic
array and the program is VERY slow. I tried
limited(<vector>, of: <double-float>)
but then the program died at runtime.

--
Waldek Hebisch
heb...@math.uni.wroc.pl or heb...@hera.math.uni.wroc.pl

Faried Nawaz

unread,
Jul 11, 2002, 6:21:10 AM7/11/02
to
heb...@math.uni.wroc.pl (Waldek Hebisch) wrote in message news:<aghjiv$lt6$1...@panorama.wcss.wroc.pl>...

> -- How one prints a floating point number. I was able
> to find examples of format, but only for integers

Use the %= control sequence with format.

format-out("%=", 2.3 * 9.443341) => 21.7196843d0

For the guts: gd/src/common/print/print.dylan


> -- How one conwerts between numbers and strings (both integers
> and floating point)

Use the common-extensions library. It has float-to-string, integer-to-string,
string-to-integer, and number-to-string.


> -- How one declares an array of doubles. Currently I use generic
> array and the program is VERY slow. I tried
> limited(<vector>, of: <double-float>)
> but then the program died at runtime.

How did it die? Can you post the code?

I tried this (which worked):

define constant <double-vector> = limited(<vector>, of: <double-float>);

define function vector-foo() => ()
let dvec :: <double-vector> = make(<double-vector>, size: 10000, fill: 0.0);

for (i from 0 below dvec.size)
// i wanted to fill this with random numbers, but i couldn't find
// random() in common-extensions.
dvec[i] := i * 1.64;
end for;

for (i from 0 below dvec.size)
format-out("%d %=\n", i, dvec[i])
end for;
end function vector-foo;

With size: 10000000 and without the format-out loop, it still took 13 seconds
on my 800MHz Athlon box.

Rob Myers

unread,
Jul 11, 2002, 11:49:37 AM7/11/02
to
On Thursday, 11, 2002, at 10:30AM, Faried Nawaz <f...@hungry.com> wrote:

>heb...@math.uni.wroc.pl (Waldek Hebisch) wrote in message news:<aghjiv$lt6$1...@panorama.wcss.wroc.pl>...
>
>> -- How one prints a floating point number. I was able
>> to find examples of format, but only for integers
>
>Use the %= control sequence with format.
>
> format-out("%=", 2.3 * 9.443341) => 21.7196843d0
>
>For the guts: gd/src/common/print/print.dylan

If you don't want the trailing d0, use %s with the float-to-string function. Which chops it off for you. :-)

- Rob.


Waldek Hebisch

unread,
Jul 12, 2002, 8:40:51 AM7/12/02
to
Faried Nawaz (f...@hungry.com) wrote:
: heb...@math.uni.wroc.pl (Waldek Hebisch) wrote in message news:<aghjiv$lt6$1...@panorama.wcss.wroc.pl>...

: > -- How one prints a floating point number. I was able
: > to find examples of format, but only for integers

: Use the %= control sequence with format.

: format-out("%=", 2.3 * 9.443341) => 21.7196843d0

: For the guts: gd/src/common/print/print.dylan

With format-out my gwydion-dylan-2.3.8 prints:
Error: Undefined variable: format-out

When I change it to format it prints:
{an instance of <double-float>}

: > -- How one conwerts between numbers and strings (both integers
: > and floating point)

: Use the common-extensions library. It has float-to-string, integer-to-string,
: string-to-integer, and number-to-string.

I get:
In Define Method main{<byte-string>}:
"hello-world.dylan", line 22, characters 18 through 32:
format("%s\n", float-to-string( 0.123) );
^^^^^^^^^^^^^^^
Error: Undefined variable: float-to-string

: > -- How one declares an array of doubles. Currently I use generic


: > array and the program is VERY slow. I tried
: > limited(<vector>, of: <double-float>)
: > but then the program died at runtime.

: How did it die? Can you post the code?

: I tried this (which worked):

: define constant <double-vector> = limited(<vector>, of: <double-float>);

: define function vector-foo() => ()
: let dvec :: <double-vector> = make(<double-vector>, size: 10000, fill: 0.0);

: for (i from 0 below dvec.size)
: // i wanted to fill this with random numbers, but i couldn't find
: // random() in common-extensions.
: dvec[i] := i * 1.64;
: end for;

: for (i from 0 below dvec.size)
: format-out("%d %=\n", i, dvec[i])
: end for;
: end function vector-foo;

: With size: 10000000 and without the format-out loop, it still took 13 seconds
: on my 800MHz Athlon box.

Well, I had to change format-out to format. Then Gwydion Dylan 2.3.4 gives:

No applicable methods in call of {the <generic-function> make} when given arguments:
#[{an instance of <limited-collection>}, #"size", 100, #"fill", {an instance of <double-float>}]
Aborted (core dumped)

Under 2.3.8 it works. I had no idea that I am hitting unimplemented
stuff :-(. I got an e-mail from Thomas V. Williams after which I
decided to upgrade my Dylan. Still, the program (simple heapsort benchmark)
works as slow as previously -- many times slower then C, 15 times slower
then CMU Common Lisp (generated C code still calls what looks like generic
methods). At least I know I gave the compiler all possible help.

Thanks for help

Rob Myers

unread,
Jul 12, 2002, 10:03:40 AM7/12/02
to
On Friday, 12, 2002, at 12:45AM, Waldek Hebisch <heb...@math.uni.wroc.pl> wrote:

>With format-out my gwydion-dylan-2.3.8 prints:
> Error: Undefined variable: format-out

Try:
make-dylan-app test .
make
./test
This should compile and run OK. If not, there's a problem with the GD installation.
Now look at test-exports.dylan. The library imports io and the module imports format-out. main() then calls format-out. This works under my 2.3.8, and prints floats as described when I add them to the format-out call.

> Error: Undefined variable: float-to-string

If the library and the module both import common-dylan then float-to-string works fine .

>: for (i from 0 below dvec.size)

Put a type constraint on i to improve performance. Probably:

for( i :: <integer> from 0 below dvec.size)

>: // i wanted to fill this with random numbers, but i couldn't find
>: // random() in common-extensions.

Use the random library and module. See:

http://www.gwydiondylan.org/gdref/gdlibs/libs-random-random.html

>: dvec[i] := i * 1.64;

Note the implicit type conversion. I don't know what to do about this. :-)

Can we populate a vector with values from a function? This would be quicker than making then populating. Or some sort of applying or mapping function.

>: for (i from 0 below dvec.size)

Again, a type constraint will improve performance here.

>Still, the program (simple heapsort benchmark)
>works as slow as previously -- many times slower then C, 15 times slower
>then CMU Common Lisp (generated C code still calls what looks like generic
>methods).

Please can you post the code so we can have a look. Fast Dylan is different from fast C (and subtly different from fast Lisp).

Thanks.

- Rob.

Andreas Bogk

unread,
Jul 12, 2002, 9:47:06 AM7/12/02
to
heb...@math.uni.wroc.pl (Waldek Hebisch) writes:

> With format-out my gwydion-dylan-2.3.8 prints:
> Error: Undefined variable: format-out

You need to import the proper libraries and modules:

module: dylan-user

define library hello-world
use common-dylan;
use io;
end library;

define module hello-world
use common-dylan;
use format-out;
end module;


> format("%s\n", float-to-string( 0.123) );
> ^^^^^^^^^^^^^^^
> Error: Undefined variable: float-to-string

You need to import the module common-extensions, which makes the
above:

define library hello-world
use common-dylan;
use io;
end library;

define module hello-world
use common-dylan;
use common-extensions;
use format-out;
end module;

> Under 2.3.8 it works. I had no idea that I am hitting unimplemented
> stuff :-(.

Yes, 2.3.4 is a bit outdated.

> decided to upgrade my Dylan. Still, the program (simple heapsort benchmark)
> works as slow as previously -- many times slower then C, 15 times slower

Could you post the code for comparison please? It's hard to say
whether that's an oversight in your code or the compiler without
seeing the code.

Andreas

--
"In my eyes it is never a crime to steal knowledge. It is a good
theft. The pirate of knowledge is a good pirate."
(Michel Serres)

Waldek Hebisch

unread,
Jul 12, 2002, 12:22:27 PM7/12/02
to
Andreas Bogk (and...@andreas.org) wrote:

: > works as slow as previously -- many times slower then C, 15 times slower

: Could you post the code for comparison please? It's hard to say
: whether that's an oversight in your code or the compiler without
: seeing the code.

Well, heapsort is on another machine (off-line) but the following
shows the problem:

define constant <my-double-vector> = limited(<vector>, of: <double-float>);

define function vector-foo(dvec :: <my-double-vector>) => ();
let n :: <integer> = dvec.size;
for (i :: <integer> from 0 below n)
dvec[i] := dvec[i] + 1.64;
end for;
end vector-foo;

define method main (argv0 :: <byte-string>, #rest noise)
let ary :: <my-double-vector> =
make(<my-double-vector>, size: 10000, fill: 0.0);
for (i from 1 to 100)
vector-foo(ary)
end for;
/* Printout so result is used */
if(ary[99] > 30)
format("Good\n");
else
format("Bad\n");
end if;
end;

It takes 1.23s on 800 MHz Athlon.
If I make scalar computations, then d2c uses C doubles for arithmetic,
but vectors are handled by generic code. I tried to make upper limit
fixed (defeats my purpose, but ...) however program runs only slightly
faster.

Bruce Hoult

unread,
Jul 12, 2002, 7:06:19 PM7/12/02
to
In article <agmvo3$fq3$1...@panorama.wcss.wroc.pl>,
heb...@math.uni.wroc.pl (Waldek Hebisch) wrote:

> It takes 1.23s on 800 MHz Athlon.

OK, it's the same speed on my 700 MHz Athlon (d2c 2.3.9pre2). Let's
take a look...

dvec[i] := dvec[i] + 1.64;

Unfortunately, all three of the operations here are going through full
generic function dispatch. You've done everything right, but we could
do a bit more work on this part of d2c. We only got support for limited
vectors into the compiler at all a couple of versions ago and at the
moment it works, but is only optimized for some data types.

I'm afraid that the best you can do at the moment using portable Dylan
is to use a plain vector...

define constant <my-double-vector> = <simple-object-vector>;

... and then introduce a temporary variable...

let elem :: <double-float> = dvec[i];
dvec[i] := elem + 1.64;

This reduces the time to 0.507 seconds. Every double is still being
allocated on the heap, which isn't good.

-- Bruce

Bruce Hoult

unread,
Jul 12, 2002, 9:13:23 PM7/12/02
to
In article <bruce-103AB8....@copper.ipg.tsnz.net>,
Bruce Hoult <br...@hoult.org> wrote:

> Unfortunately, all three of the operations here are going through full
> generic function dispatch. You've done everything right, but we could
> do a bit more work on this part of d2c. We only got support for limited
> vectors into the compiler at all a couple of versions ago and at the
> moment it works, but is only optimized for some data types.

I've got some good news for you. I've just checked some modifications
into cvs for the compiler which implement unboxed vectors of doubles.
It took five lines of code :-)


With one simple change your program now runs in 0.02 seconds instead of
1.23 seconds. After increasing the number of iterations from 100 to
10,000 it takes 0.76 seconds. So Dylan just got 160 times faster for
this type of program.


Here is the Dylan and generated x86 machine code for vector-foo():

define function vector-foo(dvec :: <my-double-vector>) => ();
let n :: <integer> = dvec.size;
for (i :: <integer> from 0 below n)

dvec[i] := dvec[i] + 1.64;

end for;
end vector-foo;

0x8049440 <vector_foo_FUN>: mov 0x8(%esp,1),%edx
0x8049444 <vector_foo_FUN+4>: xor %eax,%eax
0x8049446 <vector_foo_FUN+6>: fldl 0x812eaa8
0x804944c <vector_foo_FUN+12>: mov 0x8(%edx),%ecx
0x804944f <vector_foo_FUN+15>: nop
0x8049450 <vector_foo_FUN+16>: cmp %ecx,%eax
0x8049452 <vector_foo_FUN+18>: jge 0x8049461 <vector_foo_FUN+33>
0x8049454 <vector_foo_FUN+20>: fldl 0x10(%edx,%eax,8)
0x8049458 <vector_foo_FUN+24>: fadd %st(1),%st
0x804945a <vector_foo_FUN+26>: fstpl 0x10(%edx,%eax,8)
0x804945e <vector_foo_FUN+30>: inc %eax
0x804945f <vector_foo_FUN+31>: jmp 0x8049450 <vector_foo_FUN+16>
0x8049461 <vector_foo_FUN+33>: fstp %st(0)
0x8049463 <vector_foo_FUN+35>: ret
0x8049464 <vector_foo_FUN+36>: lea 0x0(%esi),%esi
0x804946a <vector_foo_FUN+42>: lea 0x0(%edi),%edi


I suspect this now beats CMUCL :-) You're welcome.


The change is this:

define constant <my-double-vector>
= limited(<simple-vector>, of: <double-float>);

If you declare it as a limited version of <vector> then the compiler
doesn't know whether vector-foo() is going to receive a fixed size or
stretchy vector and so you get non-optimal code. So we make sure it
knows that it's going to get a fixed-size vector...

-- Bruce

Bruce Hoult

unread,
Jul 12, 2002, 9:19:05 PM7/12/02
to
In article <bruce-A23476....@copper.ipg.tsnz.net>,
Bruce Hoult <br...@hoult.org> wrote:

> In article <bruce-103AB8....@copper.ipg.tsnz.net>,
> Bruce Hoult <br...@hoult.org> wrote:
>
> > Unfortunately, all three of the operations here are going through full
> > generic function dispatch. You've done everything right, but we could
> > do a bit more work on this part of d2c. We only got support for limited
> > vectors into the compiler at all a couple of versions ago and at the
> > moment it works, but is only optimized for some data types.
>
> I've got some good news for you. I've just checked some modifications
> into cvs for the compiler which implement unboxed vectors of doubles.
> It took five lines of code :-)
>
>
> With one simple change your program now runs in 0.02 seconds instead of
> 1.23 seconds. After increasing the number of iterations from 100 to
> 10,000 it takes 0.76 seconds. So Dylan just got 160 times faster for
> this type of program.
>
>
> Here is the Dylan and generated x86 machine code for vector-foo():
>
> define function vector-foo(dvec :: <my-double-vector>) => ();
> let n :: <integer> = dvec.size;
> for (i :: <integer> from 0 below n)
> dvec[i] := dvec[i] + 1.64;
> end for;
> end vector-foo;

Oh, and this is just as fast:

define function vector-foo(dvec :: <my-double-vector>) => ();

for (i from 0 below dvec.size)

dvec[i] := dvec[i] + 1.64;
end for;
end vector-foo;

Once the compiler knows for sure it has a fixed-size vector, it can
figure out for itself that the size is an integer, and therefore so is
the loop counter variable.

-- Bruce

Andreas Bogk

unread,
Jul 13, 2002, 6:06:42 AM7/13/02
to
Bruce Hoult <br...@hoult.org> writes:

> With one simple change your program now runs in 0.02 seconds instead of
> 1.23 seconds. After increasing the number of iterations from 100 to
> 10,000 it takes 0.76 seconds. So Dylan just got 160 times faster for
> this type of program.

Bruce, you rock :).

Bruce Hoult

unread,
Jul 13, 2002, 7:19:08 AM7/13/02
to
In article <87u1n4n...@andreas.org>,
Andreas Bogk <and...@andreas.org> wrote:

> Bruce Hoult <br...@hoult.org> writes:
>
> > With one simple change your program now runs in 0.02 seconds instead of
> > 1.23 seconds. After increasing the number of iterations from 100 to
> > 10,000 it takes 0.76 seconds. So Dylan just got 160 times faster for
> > this type of program.
>
> Bruce, you rock :).

Nah, I just tweaked Eric Kidd's optimizer work for limited vectors.
Like many things in d2c, the framework is there and quite sound, but it
just needs a few i's dotted and t's crossed here and there. Which often
requires only possesion of a Round Tuit ... or someone to need some
feature and ask for it.

-- Bruce

Rob Myers

unread,
Jul 13, 2002, 9:18:58 AM7/13/02
to
On Saturday, 13, 2002, at 01:15AM, Bruce Hoult <br...@hoult.org> wrote:

>I suspect this now beats CMUCL :-)

That's nice. :-)

- Rob.

Waldek Hebisch

unread,
Jul 13, 2002, 4:19:58 PM7/13/02
to
Bruce Hoult (br...@hoult.org) wrote:
: In article <bruce-103AB8....@copper.ipg.tsnz.net>,
: Bruce Hoult <br...@hoult.org> wrote:

: I've got some good news for you. I've just checked some modifications

: into cvs for the compiler which implement unboxed vectors of doubles.
: It took five lines of code :-)


: With one simple change your program now runs in 0.02 seconds instead of
: 1.23 seconds. After increasing the number of iterations from 100 to
: 10,000 it takes 0.76 seconds. So Dylan just got 160 times faster for
: this type of program.

<snip>

: I suspect this now beats CMUCL :-) You're welcome.


: The change is this:

: define constant <my-double-vector>
: = limited(<simple-vector>, of: <double-float>);

: If you declare it as a limited version of <vector> then the compiler
: doesn't know whether vector-foo() is going to receive a fixed size or
: stretchy vector and so you get non-optimal code. So we make sure it
: knows that it's going to get a fixed-size vector...

: -- Bruce

Good work, I fetched new version from CVS and I will try it.
Thanks

Faried Nawaz

unread,
Jul 15, 2002, 7:46:50 AM7/15/02
to
Lame followup:


-- cmucl --
;; might be faster to use something other than loop. maybe.

;; assign each element to element-number + 1.64.
;; it took me lots of searching around to figure out the right type
;; declaration for dvec.
(defun vector-foo (dvec)
(declare (optimize (speed 3) (debug 0) (safety 0))
(type (simple-array double-float (*)) dvec))
(loop for i of-type fixnum from 0 below (length dvec) by 1 do
(setf (aref dvec i) (+ i 1.64d0))))

;; make a 1,000,000 element array, each type double-float, each element 0.0.
;; operate on it 1000 times.
(defun main ()
(let ((ary (make-array 1000000
:initial-element 0.0d0
:element-type 'double-float
:adjustable nil)))
(loop for i of-type fixnum from 1 to 1000 do
(vector-foo ary))))
-- cmucl --

;; i manually compiled vector-foo and main before doing this:
* (time (main))
Compiling LAMBDA NIL:
Compiling Top-Level Form:

Evaluation took:
48.92 seconds of real time
44.7476 seconds of user run time
0.062151 seconds of system run time
0 page faults and
8000008 bytes consed.
NIL
*

-- dylan --

/*
create a subclass of simple-vector that has double-float elements.
note that both simple-vector and double-float are actual classes.
*/


define constant <my-double-vector> =
limited(<simple-vector>, of: <double-float>);

/*
i'm lazy, so i don't tell the compiler all the types. let it figure
out what i is an integer or whatever; dvec.size is optimized from a
object slot access to a constant.

hopefully.
*/


define function vector-foo(dvec :: <my-double-vector>) => ()

for (i from 0 below dvec.size)

dvec[i] := i + 1.64;
end for;
end function vector-foo;

// create an array, run vector-foo() on it a thousand times, quit.
define function main(name, arguments)
let ary :: <my-double-vector> =
make(<my-double-vector>, size: 1000000, fill: 0.0);
for (i from 1 to 1000)
vector-foo(ary);
end for;
exit-application(0);
end function main;

// Invoke our main() function.
main(application-name(), application-arguments());
-- dylan --

% /usr/bin/time ./dylan-version
30.21 real 27.60 user 0.02 sys
%
-- c --
void vector_foo(double *dvec, int dvec_size)
{
int i;

for (i = 0; i < dvec_size; i++)
dvec[i] = i + 1.64;
}

/* made this a global because i was exceeding my stacksize limit */
double ary[1000000];

int main()
{
int i;

for (i = 0; i < 1000; i++)
vector_foo(ary, 1000000);
_exit(0);
}
-- c --
% /usr/bin/time ./foo
30.20 real 27.59 user 0.03 sys
%


athlon 800.

Bruce Hoult

unread,
Jul 15, 2002, 5:50:39 PM7/15/02
to
In article <457e22d8.02071...@posting.google.com>,
f...@hungry.com (Faried Nawaz) wrote:

> Lame followup:
>
> -- cmucl --

> 44.7476 seconds of user run time

> -- dylan --


> 30.21 real 27.60 user 0.02 sys

> -- c --


> 30.20 real 27.59 user 0.03 sys

So Dylan is 60% faster than CMUCL, and within experiemental error of C.

Notes:

- this is a slightly different task than the previous example used

- the Dylan program is running with full safety e.g. bounds checks, type
checks. Both the C and Common Lisp programs are unsafe.

Scott McKay

unread,
Jul 15, 2002, 11:06:27 PM7/15/02
to

"Bruce Hoult" <br...@hoult.org> wrote in message
news:bruce-9A2922....@copper.ipg.tsnz.net...

This is a great result. Publish it somewhere. (Really)


0 new messages