Q: newsub and implicit registers
The 2nd version of newsub implicitly sets P0 and P1, but they are not part of the instruction. IMCC currently has a problem with this; if we have a register linked to the instruction for data flow analysis and allocation, it will be emitted as part of the opcode. Either we declare that all PASM instructions must include the registers they modify (I don't think this is feasible, but I'm not sure). or IMCC has to track implicit registers. In either case, I don't like that we have 2 versions of newsub, one that has a Px destination register and one that has P0/P1 hardcoded. I know the calling convention says P0/P1, but what do we gain by hiding it at the PASM level when we can hide it with IMCC? -Melvin
Re: How to run typeless languages fast on parrot?
Thies C. Arntzen wrote: [ most already answered, just some additional bits ] because pmc as so much slower that native types i loose most of parrots brilliant speed due to the fact that i don't know the types at compile-time. When you get rid of all the temps and the clone[1], the loop with PMCs runs at about 3 times the speed of perl5. So I'd not use the term "slow". It would be faster with native types of course, but its hard to impossible to decide at compile time, that native types do the same thing. I don't know PHP but in perl the + operator could be overloaded and calculate the phase of the moon instead of adding 5.5 ... union { Yeah, that's a PMC. ... could you explain how you are planning to make untyped languages run really fast on parrot and what direction i have to take to use that technique? AFAIK you have to work hard on your code generator. We will try to optimize a lot, but at the AST level you have much more information and can safely do it better. thies leo [1] # for ($i = 0; $i < 10_000_000; $i = $i + 5.5) { } .sub _main .sym var i i = new PerlUndef i = 0 $P0 = new PerlUndef $P0 = 1000 lp: if i >= $P0 goto ex i = i + 5.5 goto lp ex: end .end
Re: Q: newsub and implicit registers
Melvin Smith <[EMAIL PROTECTED]> wrote: > The 2nd version of newsub implicitly sets P0 and P1, but they > are not part of the instruction. Yeah. But we really have a lot more of such instructions: invoke or stack.ops for example. > or IMCC has to track implicit registers. cfg.c:109 in my tree. invoke and invokecc are handled there too. > I know the calling convention says P0/P1, but what do we gain > by hiding it at the PASM level when we can hide it with IMCC? The 4 argument form of newsub isn't really needed, that's right. > -Melvin leo
Re: HASH changes
Juergen Boemmels <[EMAIL PROTECTED]> wrote: > Hi, > the latest changes of HASH in src/hash.c makes t/src/hash.t fail > badly. Oops, sorry (but at least it isn't the only broken test currently :) > But I still have one problem: hash_put and hash_get are not > symmetric. hash_put puts a void *value, but hash_get returns a > HASHBUCKET. This looks wrong to me. When returning the value directly, we couldn't have NULL value's - or better NULL values and no entry at all would have the same return result. Additionally the returned bucket has the key inside, which could be useful. > boe leo
HASH changes
Hi, the latest changes of HASH in src/hash.c makes t/src/hash.t fail badly. It did not even compile because of the prototype change in hash_new. Ok that was easy to fix and I have already a fix in my tree, which at least compiles cleanly. But I still have one problem: hash_put and hash_get are not symmetric. hash_put puts a void *value, but hash_get returns a HASHBUCKET. This looks wrong to me. I have no problem with value being a void* but hash_get should then return also a void *. If its really needed to get a bucket it should be done with a function hash_get_bucket. (But this really feels like exposing an implementation detail). Comments boe -- Juergen Boemmels[EMAIL PROTECTED] Fachbereich Physik Tel: ++49-(0)631-205-2817 Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906 PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47
Re: Q: newsub and implicit registers
At 09:31 AM 11/6/2003 +0100, Leopold Toetsch wrote: Melvin Smith <[EMAIL PROTECTED]> wrote: > The 2nd version of newsub implicitly sets P0 and P1, but they > are not part of the instruction. Yeah. But we really have a lot more of such instructions: invoke or stack.ops for example. > or IMCC has to track implicit registers. cfg.c:109 in my tree. invoke and invokecc are handled there too. Ok, I'll have a look. Thanks, -Melvin
Re: How to run typeless languages fast on parrot?
On Wed, 5 Nov 2003, Thies C. Arntzen wrote: > hi, Hi ho, and glad to have you on-board. :) > we've started a project (will have a web-page soon) that aims to port the > php-language (www.php.net) to run on top of parrot. we've written some > initial code and i'm kinda stuck while writing the codegen (i target imc) > my problem is that php is typeless. As is perl, python, and ruby, FWIW. Luckily that's what Parrot's ultimately designed to run :) > i am writing code to to some basic > type-recognition in my ast to be able to leverage the much speedier I S and > N types in parrot, but for obvious reasons i have to make the php basic > type an PMC. problem now is that using pmc for everything will make execution > much much slower that it could be. Well... while that's true, in its own way, it's also misleading, though that's partially our fault. PMCs are Parrot's base type, and what most languages operating on it should use. I, N, and S registers are in for local optimizations--PMCs are the main data element. > my compiler currently translates: [Snippage] There are a number of spots in there that can be improved--we can work that out with you later if you like. > (i know it can be made better - working on it) - but the basic dilemma is > obvious: $i starts as an INT and becomes a FLOAT at runtime. so my compiler > made it a PMC. (i know that i'll at one point have to write my own PMC for > the PHP base-type, but for now PerlUndef works for me). It's possible one of the provided types will work out OK as well--if PHP's base variable type has the same semantics as perl's scalar, it seems to make sense to use that, just to skip out on having to rewrite the same code. > because pmc as so much slower that native types i loose most of parrots > brilliant speed due to the fact that i don't know the types at > compile-time. Nah, you still get our brilliant speed. You're just blinded by the fact that we're even faster with the primitive types. :) > would't it make sense to introduce one additional new type into parrot that > can "morph" between the normal types (I, S, N, P)? That would be a PMC. :) > if you think this is unneeded could you explain how you are planning to > make untyped languages run really fast on parrot and what direction i have > to take to use that technique? Use PMCs. > (PMC will always carry the vtable jump > overhead, so they will be slower than what perl or php use currently in the > inner execution loop) That, as they say, turns out not to be the case. PMCs are faster than the SVs that perl currently uses, and I'd bet they're quite a bit faster than what PHP uses. It's counter-intuitive, but the vtable approach has less overhead than the current integrated "check flags and figure out what to do" scheme that perl uses. (I can't speak for PHP, as I don't know the source, but I'd expect that things are the same there) A function call does, definitely, blow the processor's prefetch pipeline. You make a call and since the destination's likely unknown to the processor's prefetch decoding system the pipeline needs to be flushed and refilled from the beginning. That blows between 3 and 11 cycles depending on the processor. Which, interestingly, is the same amount of time you blow for a mispredicted branch. That means that the vtable dispatch time and an if jump take about the same time, assuming the destination for both is in L1 cache. At that point, then, you need to factor in the other costs to see what's ultimately more expensive. The vtable dispatch has an indirect pointer fetch, function arg setup, function preamble and function postamble. Luckily function preamble and postamble are generally very low-overhead, and are often nonexistant. (Unless stack space is allocated, but then it's a block entry cost rather than a functione entry cost, and a constant cost for both vtable and flag check schemes, as we can assume that the variables would be created in the body of the flag-check-handling code as well) The flag check requires the flag word be fetched out of the struct, the flag bit extracted out, and tested. This is, for a single test, slightly faster than the vtable dispatch overhead--it's more than the cost of fetching the vtable function pointer, but less than the cost to fetch the pointer and set up the args for dispatch by a cycle or three, depending on your processor. The win, then, comes in when you have to do multiple checks at the start of a function. Perl, for example, does a *lot* of checking at the start of each op function (much, but not all, of it hidden behind a few macros) and spends much more time in each op function than Parrot does, because parrot can roll almost all of those flag checks into the single vtable dispatch. The trick is to make the vtable attached to a PMC as specific to the variable ty
Re: HASH changes
Leopold Toetsch <[EMAIL PROTECTED]> writes: > Juergen Boemmels <[EMAIL PROTECTED]> wrote: > > Hi, > > > the latest changes of HASH in src/hash.c makes t/src/hash.t fail > > badly. > > Oops, sorry (but at least it isn't the only broken test currently :) I committed a partial fix. Now the tests are at least compiling. > > But I still have one problem: hash_put and hash_get are not > > symmetric. hash_put puts a void *value, but hash_get returns a > > HASHBUCKET. This looks wrong to me. > > When returning the value directly, we couldn't have NULL value's - or > better NULL values and no entry at all would have the same return > result. Yes this is a problem. I did a little research how other libraries solve this problem. Oh man, there are many of them. Far the most libraries return the value directly [1], some of them use a function to check if the key exists and set the value part as a side effect [2] and a third group uses an approach were creation is a side effect of lookup (sometimes controlled with a flag) and always return an key/value pair [3]. Glib for example use approaches [1] and [2]. Our current approach looks like a mixture of all these 3 cases. >From the principle of least surprise, I suggest to let hash_get return a value pointer directly and have the ambiguity of NULL value and no entry, and have a hash_get_bucket which returns a pointer to the bucket. void * hash_get(Interp * interpreter, HASH *hash, void *key); HASHBUCKET * hash_get_bucket(Interp * interpreter, HASH *hash, void *key); Some other note. Didn't we decided some time ago to use only ALLCAPS types in cases were they are abbreviations. So the name would better be Hash and HashBucket. > Additionally the returned bucket has the key inside, which could be > useful. In cases where two keys compare equal but are not equal bitwise this is indeed nice. bye boe [1] http://oss.software.ibm.com/cvs/icu/icu/source/common/uhash.h?rev=1.24 http://developer.gnome.org/doc/API/2.0/glib/glib-Hash-Tables.html http://apr.apache.org/docs/apr/group__apr__hash.html http://www.w3.org/Library/src/HTHash.html http://mission.base.com/peter/source/pbl/doc/ http://judy.sourceforge.net/JudySL_3x.htm http://www.ipd.bth.se/ska/sim_home/libghthash_mk2_doc/ght__hash__table_8h.html http://dodgysoftware.net/ht/ http://chilli.degnet.de/~e_decker/hashtable/ [2] http://developer.gnome.org/doc/API/2.0/glib/glib-Hash-Tables.html http://www-2.cs.cmu.edu/~bwolen/fmcad98/packages/tiger/tgrlib/utilhash.html http://www.ohse.de/uwe/strhash/libstrhash.html http://www.stalphonsos.com/~attila/libgram/docs/hash_8h.html [3] http://www.gnu.org/manual/bfd-2.9.1/html_node/bfd_43.html http://www.gnu.org/software/libc/manual/html_node/Hash-Search-Function.html http://www.tcl.tk/man/tcl8.2.3/TclLib/Hash.htm -- Juergen Boemmels[EMAIL PROTECTED] Fachbereich Physik Tel: ++49-(0)631-205-2817 Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906 PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47
Re: HASH changes
On Nov 6, 2003, at 10:05 AM, Juergen Boemmels wrote: But I still have one problem: hash_put and hash_get are not symmetric. hash_put puts a void *value, but hash_get returns a HASHBUCKET. This looks wrong to me. When returning the value directly, we couldn't have NULL value's - or better NULL values and no entry at all would have the same return result. ... From the principle of least surprise, I suggest to let hash_get return a value pointer directly and have the ambiguity of NULL value and no entry, and have a hash_get_bucket which returns a pointer to the bucket. void * hash_get(Interp * interpreter, HASH *hash, void *key); HASHBUCKET * hash_get_bucket(Interp * interpreter, HASH *hash, void *key); And to amplify what you are saying, I think it's okay for hash_get to be ambiguous as to whether or not the key exists, as long as there is a separate method for that--hash_key_exists or something. (I can't think of a case in user code where you'd need to do both in one call--in perl5 for example "exists" is a separate operator from hash lookup.) An alternative (which may or may not a good one) would be to say that you can never actually store a NULL in a hash--at most you could store a PerlUndef or Null or whatever null-ish PMC. Then a NULL return unambiguously means that the key wasn't found. I could probably argue either for or against this. JEff
Re: Re[2]: NCI Broken On Win32
From: "Mattia Barbon" <[EMAIL PROTECTED]> > Il Tue, 28 Oct 2003 18:51:56 +0100 Leopold Toetsch <[EMAIL PROTECTED]> ha scritto: > > > Jonathan Worthington <[EMAIL PROTECTED]> wrote: > > > Hi, > > > > > loadlib P1, "user32.dll" > > > > There are 2 errors in that, one is mine :) > > - I didn't use the configure define of PARROT_DLL_EXTENSION > > - Your's is: don't append ".dll" - parrot does it > Somebody might wish to load something not named ".dll". For example > MS HTMLHelp API is located in a file suffixed ".ocx" (which exports > both an ActiveX control and raw C API). This is true, and IMHO needs some thought. I'm working on a library that gives Parrot access to the entire Win32 API. Some of them (related to printing) are in a library called winspool.drv (note .drv, not .dll). Parrot adds .dll onto the end of this and, of course, it cannot load it. I'd be surprised if Win32 was the only OS where there was more than one possible extension for a shared library. Thanks, Jonathan
Re: Re[2]: NCI Broken On Win32
On Nov 6, 2003, at 3:59 PM, Jonathan Worthington wrote: From: "Mattia Barbon" <[EMAIL PROTECTED]> Il Tue, 28 Oct 2003 18:51:56 +0100 Leopold Toetsch <[EMAIL PROTECTED]> ha scritto: Jonathan Worthington <[EMAIL PROTECTED]> wrote: Hi, loadlib P1, "user32.dll" There are 2 errors in that, one is mine :) - I didn't use the configure define of PARROT_DLL_EXTENSION - Your's is: don't append ".dll" - parrot does it Somebody might wish to load something not named ".dll". For example MS HTMLHelp API is located in a file suffixed ".ocx" (which exports both an ActiveX control and raw C API). This is true, and IMHO needs some thought. I'm working on a library that gives Parrot access to the entire Win32 API. Some of them (related to printing) are in a library called winspool.drv (note .drv, not .dll). Parrot adds .dll onto the end of this and, of course, it cannot load it. I'd be surprised if Win32 was the only OS where there was more than one possible extension for a shared library. Yeah, this would likely be a problem on Mac OS X as well, where loadable bundles can have a variety of extensions. I'm of the opinion that there's no very good reason to not just have the API take a real file name (including the extension). I can imagine enforcing a per-platform extension for parrot bytecode libs specifically, so that you can write platform-independent user code which doesn't have to worry about how a parrot add-on lib is named, but then again it would be just as sensible to have a cross-platform convention for the extension, and just use the file name even here. JEff