...it seems! Hi Monks.

(This node has no special purpose other than to inform you what to expect to happen with perl-scripts on the new and glorious IA-64 architecture.)

This is a code snippet I got from somewhere in the net (donīt remember anymore from where). It aims to be genetic code - it is a little bit - to approximate through evolutionary principles a certain number sequence by an expression.

The really astonishing fact about this code snippet is, that on a Athlon 900 it runs much faster than on a SMP Itanium IA-64 (thats not astonishing) PLUS that on the Itanium, the code nearly always breaks perl (that IS astonishing).

Though the Itanium has 1GB of RAM, execution ends with an Out of memory! when theres still some 800MB of RAM left. Perl is

rj@goliath: perl -V Summary of my perl5 (revision 5.0 version 6 subversion 0) configuratio +n: Platform: osname=linux, osvers=2.4.3, archname=ia64-linux uname='linux d106 2.4.3 #1 smp mon may 14 17:07:47 gmt 2001 ia64 u +nknown ' config_args='-ds -e -Dprefix=/usr -Di_db -Di_dbm -Di_ndbm -Di_gdbm + -Doptimize=-O0' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultipl +icity=undef useperlio=undef d_sfio=undef uselargefiles=define use64bitint=define use64bitall=define uselongdouble=undef usesocks +=undef Compiler: cc='cc', optimize='-O0', gccversion=2.96-ia64-000717 snap 001117 cppflags='-fno-strict-aliasing -I/usr/local/include' ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_S +OURCE -D_FILE_OFFSET_BITS=64' stdchar='char', d_stdstdio=define, usevfork=false intsize=4, longsize=8, ptrsize=8, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1 +6 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', + lseeksize=8 alignbytes=8, usemymalloc=n, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lc -lcrypt libc=, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynami +c' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: USE_64_BIT_INT USE_64_BIT_ALL USE_LARGE_FILES Built under linux Compiled at May 22 2001 13:16:28 @INC: /usr/lib/perl5/5.6.0/ia64-linux /usr/lib/perl5/5.6.0 /usr/lib/perl5/site_perl/5.6.0/ia64-linux /usr/lib/perl5/site_perl/5.6.0 /usr/lib/perl5/site_perl .

Code is here:

#!/usr/bin/perl -w # Based on ideas and code by Brad Murray (bjm@a2b01118.paralynx.bconne +cted.net), # posted to perl-ai list June 3 1999. Completed and maintained by Ken # Williams (ken@forum.swarthmore.edu). # VERSION: $Revision: 1.4 $ use strict; my @functions = ( # Format is 'function <pretty version>: <actual code> +' 'function add($a,$b): ($a+$b)', 'function mul($a,$b): ($a*$b)', 'function sin($a,$b): sin($a)', 'function log($a,$b): do{my $_a=$a; $_a ? log(abs($_a +)) : 0}', ); my @terminals = ( sub {'$x'}, sub {'$x'}, sub { int(rand(20) - 10) }, sub { int(rand(20) - 10) }, ); my $maxdepth = 5; my $pop = 20; my $mates = 5; my $gen = 200; # Get target data set my @target = split ',', scalar <DATA>; # Build a starting population of $pop Organisms my @world = map {{organism => new Organism}} 1..$pop; my $count = 0; while ($count<$gen) { print "\nGENERATION ", ++$count, "\n"; foreach (@world) { $_->{fitness} = &fitness($_->{organism},@target); $_->{as_string} = $_->{organism}->as_string; } @world = sort { $a->{fitness} <=> $b->{fitness} or length $a->{as_string} <=> length $b->{as_string} } @world; foreach (@world) { print "=================== Fitness: $_->{fitness} ================ +===\n"; print $_->{as_string}, "\n"; } # Kill off some organisms, mate some others to take their spots. We # mate the top n organisms with random elements from the population. for (1..$mates) { pop @world; my ($org1, $org2) = ($world[$mates-1]{organism}, $world[rand @worl +d]{organism}); ($org1, $org2) = ($org2, $org1) if int rand 2; # Maybe switch role +s my $child = $org1->mate($org2); unshift @world, {organism => $child}; print "Created '@{[$child->as_string]}' from '@{[$org1->as_string] +}' and '@{[$org2->as_string]}'\n"; } # mutate one organism at random my $to_mutate = $world[rand @world]{organism}; print "Mutated '@{[$to_mutate->as_string]}' into "; $to_mutate->mutate; print "'@{[$to_mutate->as_string]}'\n"; # Uncomment if you want to watch each step #print "<RETURN> to continue:"; <STDIN>; } sub fitness { # Determine the fitness of an organism in this crazy world my ($org, @target) = @_; my $sumdiff = 0; foreach (0..$#target) { $sumdiff += abs($org->evaluate({'x'=>$_}) - $target[$_]); } return $sumdiff/@target; } ##################################################################### package Organism; use Storable qw(dclone store); # Syntax tree is a set of hash entries: # $node->{a} = $another_node or undef # $node->{b} = $another_node or undef # $node->{contents} = $function or 'x' or constant # # Example: # sin(7 * log($x)) # # sin(multiply(7,log($x,0)),0) # # sin # / \ # / \ # multiply 0--undef # / \ \ # 7 log undef # / \ / \ # undef undef x 0--undef # / \ \ # undef \ undef # undef # # In Perl data structures: # { contents => 'function sin($a,$b): sin($a)', # a => { # contents => 'function mul($a,$b): ($a*$b)', # a => 7, # b => { # contents => 'function log($a,$b): do{my +$_a=$a; $_a ? log(abs($_a)) : 0}', # a => '$x', # b => 0, # }, # }, # b => 0, # } sub new { my $package = shift; my $self = {tree => $package->_buildTree() }; return bless $self, $package; } sub _buildTree { my $self = shift; my $depth = shift || 0; my %tree; $tree{contents} = ($depth > $maxdepth or int rand(3)) ? &{$terminals[rand @terminals]} : $functions[rand @functions]; # 'a' and 'b' are the two arguments to functions if ($tree{contents} =~ /^function /) { $tree{'a'} = $self->_buildTree($depth + 1); $tree{'b'} = $self->_buildTree($depth + 1); } return \%tree; } sub _treeIndex { # Generates a list of all the nodes in this tree. These are # references to the stuff in the object itself, so changes to the # elements of this list will change the object. my $self = shift; my $tree = shift || $self->{tree}; my @sofar = @_; # Dump the content nodes into a list if ($tree->{contents} =~ /^function /) { return(@sofar, $tree, $self->_treeIndex($tree->{'a'}, @sofar), $self->_treeIndex($tree->{'b'}, @sofar) ); } else { return(@sofar, $tree); } } sub mate { my ($self, $partner) = @_; my $self_clone = dclone $self; # Get part of a node from $partner and stick it somewhere in $self_c +lone my @clone_index = $self_clone->_treeIndex; my @partner_index = $partner->_treeIndex; %{ $clone_index[rand @clone_index] } = %{ dclone $partner_index[rand + @partner_index] }; $self_clone->clear_cache; return $self_clone; } sub mutate { my $self = shift; my @index = $self->_treeIndex; %{ $index[rand @index] } = %{ $self->_buildTree($maxdepth-1) }; $self->clear_cache; } sub evaluate { my $self = shift; my $params = shift; my $x = $params->{'x'}; return eval $self->expression; } sub expression { # Turn the syntax tree into a Perl expression my $self = shift; my $tree = shift || $self->{tree}; # Check the cache return $self->{expr} if defined $self->{expr}; local $_ = $tree->{contents}; # A shortcut for the current node if ( s/^function [^:]*: (.*)/$1/ ) { # Extract the perl expression s/\$([a-zA-Z]+)/$self->expression($tree->{$1})/ge; } $self->{expr} = $_ if $tree eq $self->{tree}; # A nasty trick return $_; } sub as_string { # Turn the syntax tree into a readable expression my $self = shift; my $tree = shift || $self->{tree}; # Check the cache return $self->{string} if defined $self->{string}; local $_ = $tree->{contents}; # A shortcut for the current node if ( s/^function ([^:]*):.*/$1/ ) { # Extract the format picture s/\$([a-zA-Z]+)/$self->as_string($tree->{$1})/ge; } $self->{string} = $_ if $tree eq $self->{tree}; # A nasty trick return $_; } sub clear_cache { # Invalidate the cached information. Typically done after mutation # or mating, because the cache represents the old data. my $self = shift; $self->{expr} = $self->{string} = undef; } __END__ -1407,-931,-577,-327,-163,-67,-21,-7,-7,-3,23,89,213,413,707,1113,1649

Edit: Footpad, 3 Aug 2001 - 7:37 am (PDT)


In reply to Genesis ainīt that easy by PetaMem

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.