[Haskell-cafe] POSIX AIO (asych I/O) ...

2008-07-01 Thread Galchin, Vasili
Hello,

   I am also testing my aio support. The aio_write binding seems to work
ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a
really simple binding. I always receive nbytes as 0. I have been staring at
the code hoping to catch a stupid mistake. I put putStrLn's in the code.
.Here is the code ...

aioReturn :: AIOCB -> IO (AIOCB, ByteCount)
aioReturn aiocb = do
   allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
  poke p_aiocb aiocb
  count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return  p_aiocb)
  aiocb <- peek p_aiocb
  return (aiocb, fromIntegral count)

foreign import ccall safe "aio.h aio_return"
c_aio_return :: Ptr AIOCB -> IO CInt

Maybe someone can spot something that I haven't.

Thanks, Vasili
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] POSIX AIO (asych I/O) ...

2008-07-01 Thread Bulat Ziganshin
Hello Vasili,

Tuesday, July 1, 2008, 11:42:26 AM, you wrote:

looks ok, show us your peek/poke code


> Hello,

>    I am also testing my aio support. The aio_write binding
> seems to work ok .. as well as aio_error, Aio_return is a problem
> child. I think I wrote a really simple binding. I always receive
> nbytes as 0. I have been staring at the code hoping to catch a
> stupid mistake. I put putStrLn's in the code. .Here is the code ...
>  
> aioReturn :: AIOCB -> IO (AIOCB, ByteCount)
> aioReturn aiocb = do
>    allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
>   poke p_aiocb aiocb
>   count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return  p_aiocb)
>    aiocb <- peek p_aiocb
>   return (aiocb, fromIntegral count)

> foreign import ccall safe "aio.h aio_return"
>     c_aio_return :: Ptr AIOCB -> IO CInt

> Maybe someone can spot something that I haven't. 
>  
> Thanks, Vasili
>   


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The ping method in HDBC

2008-07-01 Thread Agent Zhang
On Mon, Jun 30, 2008 at 9:31 PM, John Goerzen <[EMAIL PROTECTED]> wrote:
>
> run dbh "SELECT 1" []
>
> I note from the Perl DBI documentation that it is not guaranteed that
> its ping function actually does anything.

Okay, thanks :)
>
> I am pondering connection pools in HDBC for the future, if I have the
> need for it.
>

That'll be great ;)

Best,
-agentzh
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Joachim Breitner
Hi,

thanks for your comments.

Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram:
> 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
> and there are a lot of gotchas involved that you may not have fully
> thought out.  But you do meet the main criteria (file being read is
> assumed to be constant for a single run of the program).

Any other gotcha? Anyways, is this really worse than the similary lazy
readFile? Using that would not safe the call to open, but at least the
reading and processing, in the same situations.

> If you have the ability to store metadata about the computation along
> with the computation results, maybe that would be a better solution?

Not sure what you mean here, sorry. Can you elaborate?

> 2) I agree with Luke that this "smells" more like an applicative
> functor.  But getting to monad syntax is quite nice if you can do so.
> As an applicative functor you would have "writeFileOD :: Filename ->
> ODIO ByteString -> ODIO ()"; then writeFile can handle all the
> necessary figuring out of timestamps itself, and you get the bonus
> guarantee that the contents of the files read by the "ODIO ByteString"
> argument won't affect the filename you are going to output to.

I thought about this (without having the applicative abstraction in
mind). This would then look like:

main = do
  f1 <- readFileOD "infile1"
  f2 <- readFileOD "infile2"
  writeFileOD "outfile1" $ someFunc <$> f1 <*> f2
  writeFileOD "outfile2" $ someOtherFunc <$> f1

right? Will it still work so that if both outfiles need to be generated,
f1 is read only once?

> 3) Instead of (Read,Show), look into Data.Binary instead, if you
> actually care about efficiency.  Parsing text at read time will almost
> never be faster than just performing the computation on the source
> data again.

I assume it’s still faster than, e.g., running an external program to
read the exif tags, but you are right, Data.Binary is nicer for this.


Thanks,
Joachim
-- 
Joachim "nomeata" Breitner
  mail: [EMAIL PROTECTED] | ICQ# 74513189 | GPG-Key: 4743206C
  JID: [EMAIL PROTECTED] | http://www.joachim-breitner.de/
  Debian Developer: [EMAIL PROTECTED]


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] POSIX AIO (asych I/O) ...

2008-07-01 Thread Galchin, Vasili
instance Storable AIOCB where

sizeOf _ = (#const sizeof (struct aiocb))

alignment _ = 1

poke p_AIOCB (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf
aioBytes aioSigevent) = do

   (#poke struct aiocb, aio_fildes) p_AIOCB aioFd

   (#poke struct aiocb, aio_lio_opcode) p_AIOCB aioLioOpcode

   (#poke struct aiocb, aio_reqprio) p_AIOCB aioReqPrio

   (#poke struct aiocb, aio_offset) p_AIOCB aioOffset

   (#poke struct aiocb, aio_buf) p_AIOCB aioBuf

   (#poke struct aiocb, aio_nbytes) p_AIOCB aioBytes

   (#poke struct aiocb, aio_sigevent) p_AIOCB aioSigevent

peek p_AIOCB = do

   aioFd <- (#peek struct aiocb, aio_fildes) p_AIOCB

   aioLioOpcode <- (#peek struct aiocb, aio_lio_opcode) p_AIOCB

   aioReqPrio <- (#peek struct aiocb, aio_reqprio) p_AIOCB

   aioOffset <- (#peek struct aiocb, aio_offset) p_AIOCB

   aioBuf <- (#peek struct aiocb, aio_buf) p_AIOCB

   aioBytes <- (#peek struct aiocb, aio_nbytes) p_AIOCB

   aioSigevent <- (#peek struct aiocb, aio_sigevent) p_AIOCB

   return (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf aioBytes
aioSigevent)



On Tue, Jul 1, 2008 at 2:48 AM, Bulat Ziganshin <[EMAIL PROTECTED]>
wrote:

> Hello Vasili,
>
> Tuesday, July 1, 2008, 11:42:26 AM, you wrote:
>
> looks ok, show us your peek/poke code
>
>
> > Hello,
>
> >I am also testing my aio support. The aio_write binding
> > seems to work ok .. as well as aio_error, Aio_return is a problem
> > child. I think I wrote a really simple binding. I always receive
> > nbytes as 0. I have been staring at the code hoping to catch a
> > stupid mistake. I put putStrLn's in the code. .Here is the code ...
> >
> > aioReturn :: AIOCB -> IO (AIOCB, ByteCount)
> > aioReturn aiocb = do
> >allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
> >   poke p_aiocb aiocb
> >   count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return  p_aiocb)
> >aiocb <- peek p_aiocb
> >   return (aiocb, fromIntegral count)
>
> > foreign import ccall safe "aio.h aio_return"
> > c_aio_return :: Ptr AIOCB -> IO CInt
>
> > Maybe someone can spot something that I haven't.
> >
> > Thanks, Vasili
> >
>
>
> --
> Best regards,
>  Bulatmailto:[EMAIL PROTECTED]
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Ketil Malde
Joachim Breitner <[EMAIL PROTECTED]> writes:

>> 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
>> and there are a lot of gotchas involved that you may not have fully
>> thought out.  But you do meet the main criteria (file being read is
>> assumed to be constant for a single run of the program).

> Any other gotcha? 

The one that springs to mind is that you might run out of file
handles. At least on Linux, that's a precious resource.

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Joachim Breitner
Hi,

Am Dienstag, den 01.07.2008, 11:53 +0200 schrieb Ketil Malde:
> Joachim Breitner <[EMAIL PROTECTED]> writes:
> 
> >> 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
> >> and there are a lot of gotchas involved that you may not have fully
> >> thought out.  But you do meet the main criteria (file being read is
> >> assumed to be constant for a single run of the program).
> 
> > Any other gotcha? 
> 
> The one that springs to mind is that you might run out of file
> handles. At least on Linux, that's a precious resource.

but at least then, (unsafeInterleaveIO readFile) is actually better than
(readFile), because if I consume the files in sequence and complete,
they will be opened and closed in sequence with the first one, but be
opened all at once with the second. At least it won’t be worse, because
the file will not be closed later, and possibly opened later.

Greetings,
Joachim


-- 
Joachim "nomeata" Breitner
  mail: [EMAIL PROTECTED] | ICQ# 74513189 | GPG-Key: 4743206C
  JID: [EMAIL PROTECTED] | http://www.joachim-breitner.de/
  Debian Developer: [EMAIL PROTECTED]


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Anglo Haskell 2008

2008-07-01 Thread Matthew Sackman
Anglo Haskell is a gathering of all people Haskell-related from
beginners, to seasoned hackers to academic giants. All and more are
welcomed by large fuzzy green lambdas.

Anglo Haskell has happened for the last two years and we see no reason
why it should not happen again this year. For the last two years they've
tended to have talks on Fridays and then Other Things on the Saturday
(including Punting and Group Hacking, some or more of which may have
happened in Pubs). We're proposing the same general format this year.

In contrast to the last two years which have been held at MSR Cambridge
(UK), we're this year proposing to hold the event at Imperial College,
London. London is probably easier to get to and from (though more
tedious to get across) than Cambridge and we hope this will attract
people who previously have not been able to get out to Cambridge.

The proposed dates are Friday the 8th and Saturday the 9th of August.

More details are available on the wikipage:
http://www.haskell.org/haskellwiki/AngloHaskell/2008
Please feel free to add to this page.

If you're at all interested in coming along then please add your name to
the wikipage. If you're interested in giving a talk - on literally
anything Haskell related: this is not a solely theory day or solely a
practical day; anything goes which is Haskell related - then similarly
add yourself to the list of speakers.

Schedule and other details will be confirmed soon. Lodging, travel and
all other related matters will be discussed on the irc channel (and will
eventually migrate to the wikipage) #anglohaskell.

If you're free that weekend then please come along! Also, if you'd
really like to come but can't make those dates and there are many of you
then please shout loudly and things could potentially be moved, though
with the lack of time left before the event, we'd prefer to avoid this.

Matthew
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] lhs syntax highlighting in vim

2008-07-01 Thread Arthur van Leeuwen


On 11 jun 2008, at 12:29, Ian Lynagh wrote:


On Wed, Jun 11, 2008 at 01:23:58AM +0100, Eric Stansifer wrote:


The syntax highlighting file for literate haskell in vim says that  
its

maintainer is haskell-cafe@haskell.org, so hopefully one of you will
find this relevant.

In literate haskell files, vim optionally highlights the non-code  
text

according to TeX markup.  The syntax highlighting file looks for key
phrases (e.g., "\documentclass") to decide whether to use TeX markup
highlighting;  but it (erroneously, in my opinion, and at variance
with the documentation) will use TeX markup highlighting on any lhs
file that contains the '%' character anywhere in it.  The bug is in
line 74 of version 1.01 of the lhaskell.vim syntax highlighting file.


I agree that this is wrong. It used to only look at the first 20  
lines,

so we were covering the case where a TeX file began with some TeX
comments. We'd also look for ^\s*%, rather than a % anywhere. If we  
are

going to look at the whole file then checking for comments isn't
necessary.


Unfortunately that scan is not necesarily compatible with people
dynamically turning on syntax highlighting. But just searching for %
is *dead* wrong, I fully agree. I've modified the search code and  
submitted

a patch to the Vim maintainers.

With kind regards, Arthur van Leeuwen.

--

  /\/ |   [EMAIL PROTECTED]   | Work like you don't need  
the money
 /__\  /  | A friend is someone with whom | Love like you have never  
been hurt
/\/__ | you can dare to be yourself   | Dance like there's nobody  
watching




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread David Roundy
On Tue, Jul 01, 2008 at 10:22:35AM +, Joachim Breitner wrote:
> Hi,
> 
> Am Dienstag, den 01.07.2008, 11:53 +0200 schrieb Ketil Malde:
> > Joachim Breitner <[EMAIL PROTECTED]> writes:
> > 
> > >> 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
> > >> and there are a lot of gotchas involved that you may not have fully
> > >> thought out.  But you do meet the main criteria (file being read is
> > >> assumed to be constant for a single run of the program).
> > 
> > > Any other gotcha? 
> > 
> > The one that springs to mind is that you might run out of file
> > handles. At least on Linux, that's a precious resource.
> 
> but at least then, (unsafeInterleaveIO readFile) is actually better than
> (readFile), because if I consume the files in sequence and complete,
> they will be opened and closed in sequence with the first one, but be
> opened all at once with the second. At least it won’t be worse, because
> the file will not be closed later, and possibly opened later.

Indeed, the best option (in my opinion) would be

unsafeInterleaveIO readFileStrict

(where you might need to write readFileStrict).  In darcs, we use lazy IO a
lot, but never lazily read a file, precisely due to the open file handle
issue.  This works pretty well, and your scenario is precisely the one in
which unsafeInterleaveIO shines.

David


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Henning Thielemann

On Tue, 1 Jul 2008, David Roundy wrote:

> Indeed, the best option (in my opinion) would be
>
> unsafeInterleaveIO readFileStrict


How about ByteString.readFile ? This is strict and efficient.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline

2008-07-01 Thread Loup Vaillant
Hello, everyone,
I'm not sure this is the good list for this posting: I plan to write
yet another lazy graph reduction machine, using gcc, mainly for fun.
My concern right now is about one particular aspect of gcc: the tail
calls vs trampoline deathmatch.

First some clarifications:
-> By tail call, I mean a properly optimized one, which doesn't grow
the stack. Basically a jump.
-> By trampoline, I mean the infinite loop referred to as a "tiny
interpreter" in the STG paper [1]. Instead of (tail) calling a
function, we return its pointer, which will then be used for the
actual call.

I've read that trampoline calls are about 3 times as expensive as tail
calls. Instead of a (direct) jump, you have a return, followed by an
indirect call. However, testing this with gcc, I didn't manage to show
any measurable difference. What am I missing? I used -O2 on both
benchmarks, and turned off inlining (using the __noinline__
attribute). I'm running the program on a core2Duo in 32 bits mode,
using GNU/Linux Ubuntu. Should I also make separate modules to prevent
whole program analysis from gcc?

Anyway, I send you the code below, so you can test and review it. Enjoy!

[1]: 
http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz



/* This program tests the performance difference between trampoline
 * calls and tail calls.  (In the STG and related papers, trampoline
 * is referred to as "tiny interpreter")
 *
 * depending on the mode (tail call or trampoline), some code changes:
 * the return type of the code blocks, and the calls to other blocks
 * (direct tail calls or return to trampoline). Hence the macros ENTER
 * and RETURN.
 *
 * To compile it,type one of the two following commands:
 * gcc -O2 sibcall.c -D SIBCALL
 * gcc -O2 sibcall.c
 *
 * The first one will make the program use sibling calls (enabled at
 * O2), and the second one will fall back to trampoline calls
 */

#ifdef SIBCALL // tail call mode

#define ENTER(f) (f())
#define RETURN void
#define MAIN(start) start()

#else // trampoline call mode

#define ENTER(f) return f
#define RETURN void*
#define MAIN(start)  do{ void * (*f)(void) = start; \
 while (1) \
   f = (*f)(); \
   } while (0)
#endif

// Now, we can begin the generic code
#include 
#define LIMIT 10 // one billion

int counter = 0;

RETURN closure0(void);
RETURN closure1(void);


int main(int argc, char ** argv)
{
  MAIN(closure0);
  return 0;
}

__attribute__ ((__noinline__))
RETURN closure0(void)
{
  if (counter >= LIMIT) exit(0);
  counter++;
  ENTER(closure1);
}
__attribute__ ((__noinline__))
RETURN closure1(void)
{
  if (counter >= LIMIT) exit(0);
  counter++;
  ENTER(closure0);
}
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline

2008-07-01 Thread Loup Vaillant
2008/7/1 Robin Green <[EMAIL PROTECTED]>:
> I think you should use the -march flag to gcc. Otherwise you are tying
> the compiler to an ancient version of the x86 instruction set (386).

OK, let's try... Done. I used -march=nocona. I couldn't do core2 (not
available on my gcc 4.1.2 yet). Did not notice any difference...


> On Tue, 1 Jul 2008 16:57:38 +0200
> "Loup Vaillant" <[EMAIL PROTECTED]> wrote:
>
>> Hello, everyone,
>> I'm not sure this is the good list for this posting: I plan to write
>> yet another lazy graph reduction machine, using gcc, mainly for fun.
>> My concern right now is about one particular aspect of gcc: the tail
>> calls vs trampoline deathmatch.
>>
>> First some clarifications:
>> -> By tail call, I mean a properly optimized one, which doesn't grow
>> the stack. Basically a jump.
>> -> By trampoline, I mean the infinite loop referred to as a "tiny
>> interpreter" in the STG paper [1]. Instead of (tail) calling a
>> function, we return its pointer, which will then be used for the
>> actual call.
>>
>> I've read that trampoline calls are about 3 times as expensive as tail
>> calls. Instead of a (direct) jump, you have a return, followed by an
>> indirect call. However, testing this with gcc, I didn't manage to show
>> any measurable difference. What am I missing? I used -O2 on both
>> benchmarks, and turned off inlining (using the __noinline__
>> attribute). I'm running the program on a core2Duo in 32 bits mode,
>> using GNU/Linux Ubuntu. Should I also make separate modules to prevent
>> whole program analysis from gcc?
>>
>> Anyway, I send you the code below, so you can test and review it.
>> Enjoy!
>>
>> [1]:
>> http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz
>>
>>
>>
>> /* This program tests the performance difference between trampoline
>>  * calls and tail calls.  (In the STG and related papers, trampoline
>>  * is referred to as "tiny interpreter")
>>  *
>>  * depending on the mode (tail call or trampoline), some code changes:
>>  * the return type of the code blocks, and the calls to other blocks
>>  * (direct tail calls or return to trampoline). Hence the macros ENTER
>>  * and RETURN.
>>  *
>>  * To compile it,type one of the two following commands:
>>  * gcc -O2 sibcall.c -D SIBCALL
>>  * gcc -O2 sibcall.c
>>  *
>>  * The first one will make the program use sibling calls (enabled at
>>  * O2), and the second one will fall back to trampoline calls
>>  */
>>
>> #ifdef SIBCALL // tail call mode
>>
>> #define ENTER(f) (f())
>> #define RETURN void
>> #define MAIN(start) start()
>>
>> #else // trampoline call mode
>>
>> #define ENTER(f) return f
>> #define RETURN void*
>> #define MAIN(start)  do{ void * (*f)(void) = start; \
>>  while (1) \
>>f = (*f)(); \
>>} while (0)
>> #endif
>>
>> // Now, we can begin the generic code
>> #include 
>> #define LIMIT 10 // one billion
>>
>> int counter = 0;
>>
>> RETURN closure0(void);
>> RETURN closure1(void);
>>
>>
>> int main(int argc, char ** argv)
>> {
>>   MAIN(closure0);
>>   return 0;
>> }
>>
>> __attribute__ ((__noinline__))
>> RETURN closure0(void)
>> {
>>   if (counter >= LIMIT) exit(0);
>>   counter++;
>>   ENTER(closure1);
>> }
>> __attribute__ ((__noinline__))
>> RETURN closure1(void)
>> {
>>   if (counter >= LIMIT) exit(0);
>>   counter++;
>>   ENTER(closure0);
>> }
>> ___
>> Haskell-Cafe mailing list
>> Haskell-Cafe@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline

2008-07-01 Thread Peter Verswyvelen
Did you look at the generated assembly code? Although I don't know 
anything about GCC, I believe it's easy to let it generate an assembly 
listing file.


Loup Vaillant wrote:

2008/7/1 Robin Green <[EMAIL PROTECTED]>:
  

I think you should use the -march flag to gcc. Otherwise you are tying
the compiler to an ancient version of the x86 instruction set (386).



OK, let's try... Done. I used -march=nocona. I couldn't do core2 (not
available on my gcc 4.1.2 yet). Did not notice any difference...


  

On Tue, 1 Jul 2008 16:57:38 +0200
"Loup Vaillant" <[EMAIL PROTECTED]> wrote:



Hello, everyone,
I'm not sure this is the good list for this posting: I plan to write
yet another lazy graph reduction machine, using gcc, mainly for fun.
My concern right now is about one particular aspect of gcc: the tail
calls vs trampoline deathmatch.

First some clarifications:
-> By tail call, I mean a properly optimized one, which doesn't grow
the stack. Basically a jump.
-> By trampoline, I mean the infinite loop referred to as a "tiny
interpreter" in the STG paper [1]. Instead of (tail) calling a
function, we return its pointer, which will then be used for the
actual call.

I've read that trampoline calls are about 3 times as expensive as tail
calls. Instead of a (direct) jump, you have a return, followed by an
indirect call. However, testing this with gcc, I didn't manage to show
any measurable difference. What am I missing? I used -O2 on both
benchmarks, and turned off inlining (using the __noinline__
attribute). I'm running the program on a core2Duo in 32 bits mode,
using GNU/Linux Ubuntu. Should I also make separate modules to prevent
whole program analysis from gcc?

Anyway, I send you the code below, so you can test and review it.
Enjoy!

[1]:
http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz



/* This program tests the performance difference between trampoline
 * calls and tail calls.  (In the STG and related papers, trampoline
 * is referred to as "tiny interpreter")
 *
 * depending on the mode (tail call or trampoline), some code changes:
 * the return type of the code blocks, and the calls to other blocks
 * (direct tail calls or return to trampoline). Hence the macros ENTER
 * and RETURN.
 *
 * To compile it,type one of the two following commands:
 * gcc -O2 sibcall.c -D SIBCALL
 * gcc -O2 sibcall.c
 *
 * The first one will make the program use sibling calls (enabled at
 * O2), and the second one will fall back to trampoline calls
 */

#ifdef SIBCALL // tail call mode

#define ENTER(f) (f())
#define RETURN void
#define MAIN(start) start()

#else // trampoline call mode

#define ENTER(f) return f
#define RETURN void*
#define MAIN(start)  do{ void * (*f)(void) = start; \
 while (1) \
   f = (*f)(); \
   } while (0)
#endif

// Now, we can begin the generic code
#include 
#define LIMIT 10 // one billion

int counter = 0;

RETURN closure0(void);
RETURN closure1(void);


int main(int argc, char ** argv)
{
  MAIN(closure0);
  return 0;
}

__attribute__ ((__noinline__))
RETURN closure0(void)
{
  if (counter >= LIMIT) exit(0);
  counter++;
  ENTER(closure1);
}
__attribute__ ((__noinline__))
RETURN closure1(void)
{
  if (counter >= LIMIT) exit(0);
  counter++;
  ENTER(closure0);
}
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
  

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


  


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Ryan Ingram
On 7/1/08, Joachim Breitner <[EMAIL PROTECTED]> wrote:
> Hi,
>
> thanks for your comments.
>
> Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram:
> > 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
> > and there are a lot of gotchas involved that you may not have fully
> > thought out.  But you do meet the main criteria (file being read is
> > assumed to be constant for a single run of the program).
>
> Any other gotcha? Anyways, is this really worse than the similary lazy
> readFile? Using that would not safe the call to open, but at least the
> reading and processing, in the same situations.

Well, you're also (from your description) probably writing some
tracking information to an IORef of some sort.  That can happen in the
middle of an otherwise pure computation, and it's difficult to know
exactly when it'll get triggered, due to laziness.  You can probably
make it work :)

> > If you have the ability to store metadata about the computation along
> > with the computation results, maybe that would be a better solution?
>
> Not sure what you mean here, sorry. Can you elaborate?

Well, while doing the computation the first time, you can track what
depends on what.  Then you save *that* information out.  Here's an
example:

main = runODIO $ do
do
bar <- readFileOD "bar.txt"
baz <- readFileOD "baz.txt"
let result = expensiveComputation bar baz
writeFileOD "foo.bin" result

do
hat <- readFileOD "hat.txt"
let result = otherComputation hat
writeFileOD "foo2.bin" result

Now, as you mentioned before, you know that the RHS of >> doesn't
depend on the files read on the LHS.  So the two "do" blocks here are
independent.  Now, if you run with no information, you run the whole
computation, and you write out in your metadata "First we are going to
build foo.bin from bar.txt and baz.txt, and then we build foo2.bin
from hat.txt".  Now when you get to the first "do" block, you know
what computation is about to happen (since you've recorded it before),
and can check the timestamps of foo.bin, bar.txt, and baz.txt, and
potentially skip the whole thing.

Of course now the metadata depends on the script itself, but you
already had to deal with that problem :)

> > 2) I agree with Luke that this "smells" more like an applicative
> > functor.  But getting to monad syntax is quite nice if you can do so.
> > As an applicative functor you would have "writeFileOD :: Filename ->
> > ODIO ByteString -> ODIO ()"; then writeFile can handle all the
> > necessary figuring out of timestamps itself, and you get the bonus
> > guarantee that the contents of the files read by the "ODIO ByteString"
> > argument won't affect the filename you are going to output to.
>
> I thought about this (without having the applicative abstraction in
> mind). This would then look like:
>
> main = do
>  f1 <- readFileOD "infile1"
>   f2 <- readFileOD "infile2"
>  writeFileOD "outfile1" $ someFunc <$> f1 <*> f2
>  writeFileOD "outfile2" $ someOtherFunc <$> f1
>
> right?

Not exactly.  Try this:

   writeFileOD "outfile1" (someFunc <$> readFileOD "infile1" <*>
readFileOD "infile2")
   writeFileOD "outfile2" (someOtherFunc <$> readFIleOD "infile1")

(or, equivalently, replace the "<-" with "let .. in" in your data).

> Will it still work so that if both outfiles need to be generated,
> f1 is read only once?

That depends how you write it!  Remember that you can write your
applicative functor to just build up a graph of what computation might
need to be done.  You can then analyze that graph and look for sharing
if necessary.

If you want the sharing to be explicit, you need something a bit more
monad-ish.  If the type of "readFileOD" is "Filename -> ODIO (ODIO
ByteString)" then your original syntax works and gives you a chance to
pick up on the explicit sharing by labelling the result of "f1 <-
...".

  -- ryan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Joachim Breitner
Hi,

thanks again for you input. Just one small remark:

Am Dienstag, den 01.07.2008, 14:52 -0700 schrieb Ryan Ingram:
> On 7/1/08, Joachim Breitner <[EMAIL PROTECTED]> wrote:
> > Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram:
> > > 1) unsafeInterleaveIO seems like a big hammer to use for this problem,
> > > and there are a lot of gotchas involved that you may not have fully
> > > thought out.  But you do meet the main criteria (file being read is
> > > assumed to be constant for a single run of the program).
> >
> > Any other gotcha? Anyways, is this really worse than the similary lazy
> > readFile? Using that would not safe the call to open, but at least the
> > reading and processing, in the same situations.
> 
> Well, you're also (from your description) probably writing some
> tracking information to an IORef of some sort.  That can happen in the
> middle of an otherwise pure computation, and it's difficult to know
> exactly when it'll get triggered, due to laziness.  You can probably
> make it work :)

Well, for the tracking information, I can do it purely, by copying code
from StateT (or WriterT or ReaderT, I’m not sure :-)), and adapting
slightly (e.g. the (>>) optimization). So besides unsafeInterleaveIO, no
“bad, unpure stuff” should be necessary.

I think I’ll put my ideas to code soon and post it here.

Greetings,
Joachim
-- 
Joachim Breitner
  e-Mail: [EMAIL PROTECTED]
  Homepage: http://www.joachim-breitner.de
  ICQ#: 74513189
  Jabber-ID: [EMAIL PROTECTED]


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] A Monad for on-demand file generation?

2008-07-01 Thread Brandon S. Allbery KF8NH


On 2008 Jul 1, at 17:52, Ryan Ingram wrote:


Well, you're also (from your description) probably writing some
tracking information to an IORef of some sort.  That can happen in the
middle of an otherwise pure computation, and it's difficult to know
exactly when it'll get triggered, due to laziness.  You can probably
make it work :)

If you have the ability to store metadata about the computation  
along

with the computation results, maybe that would be a better solution?


Not sure what you mean here, sorry. Can you elaborate?


Well, while doing the computation the first time, you can track what
depends on what.  Then you save *that* information out.  Here's an


This sounds suspiciously like Writer to me.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Galchin, Vasili
Hello,

Haskell 101 question! I discovered that aio_error returns "errno" rather
-1. Of course, my aio_error binding is called before my aio_return binding
(aio calling sequence "protocol"). I have worked on  Posix OS's for quite a
while but am unhappy with non-consistent errno handling ;^(. In any case, I
modified my aio_error binding implementation to have a "AIOCB -> IO Errno"
signature:

aioError :: AIOCB -> IO Errno
aioError aiocb = do
   allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
  poke p_aiocb aiocb
  errno <- throwErrnoIfMinus1 "aioError" (c_aio_error  p_aiocb)
  return (errno)

foreign import ccall safe "aio.h aio_error"
c_aio_error :: Ptr AIOCB -> IO Errno

"ghc" thinks that "Errno" should be an instance of "Num":

System/Posix/Aio.hsc:117:15:
No instance for (Num Errno)


Why?

Vasili



On Tue, Jul 1, 2008 at 2:42 AM, Galchin, Vasili <[EMAIL PROTECTED]> wrote:

> Hello,
>
>I am also testing my aio support. The aio_write binding seems to
> work ok .. as well as aio_error, Aio_return is a problem child. I think I
> wrote a really simple binding. I always receive nbytes as 0. I have been
> staring at the code hoping to catch a stupid mistake. I put putStrLn's in
> the code. .Here is the code ...
>
> aioReturn :: AIOCB -> IO (AIOCB, ByteCount)
> aioReturn aiocb = do
>allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
>   poke p_aiocb aiocb
>   count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return  p_aiocb)
>   aiocb <- peek p_aiocb
>   return (aiocb, fromIntegral count)
>
> foreign import ccall safe "aio.h aio_return"
> c_aio_return :: Ptr AIOCB -> IO CInt
>
> Maybe someone can spot something that I haven't.
>
> Thanks, Vasili
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Brandon S. Allbery KF8NH


On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:


  errno <- throwErrnoIfMinus1 "aioError" (c_aio_error  p_aiocb)

"ghc" thinks that "Errno" should be an instance of "Num":

System/Posix/Aio.hsc:117:15:
No instance for (Num Errno)


I expect so it can compare it to -1(throwErrnoIfMinusOne).  But if the  
return value is actually an errno and not -1 to indicate error (which  
it is if I read the manpage correctly), you don't want  
throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value  
of c_aio_return (which should be IO CInt) in an Errno constructor,  
then use errnoToIOError if you really want to raise an IOError.


(What were you expecting for "count"?  I see none, just an errno.)

Note that it *never* returns -1; it returns 0 for successful  
completion for the aiocb, EINPROGRESS if it's still working, and the  
appropriate errno if it failed.


You might want to decide if you want to use the aio_return style  
interface or something more Haskell-ish before designing this part of  
the API.  If you want to stick close to the C interface:


aioReturn :: AIOCB -> IO (AIOCB, Errno)
aioReturn aiocb = do
   allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
  poke p_aiocb aiocb
  err <- c_aio_return  p_aiocb
  aiocb <- peek p_aiocb
  return (aiocb, Errno err)

I'd actually consider something more Haskellish, e.g. a variant of  
StateT IO where the state is the aiocb and errno, the errno  
initialized to eINPROGRESS and set by aioReturn and aioError (and once  
aioReturn is called, it can't be called again so return the cached  
value if needed).


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Jonathan Cast
On Wed, 2008-07-02 at 02:07 -0400, Brandon S. Allbery KF8NH wrote:
> 
> On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
> 
> >   errno <- throwErrnoIfMinus1 "aioError" (c_aio_error  p_aiocb)
> > 
> > "ghc" thinks that "Errno" should be an instance of "Num":
> > 
> > System/Posix/Aio.hsc:117:15:
> > No instance for (Num Errno)
> 
> 
> I expect so it can compare it to -1(throwErrnoIfMinusOne).  But if the
> return value is actually an errno and not -1 to indicate error (which
> it is if I read the manpage correctly), you don't want
> throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value
> of c_aio_return (which should be IO CInt) in an Errno constructor,
> then use errnoToIOError if you really want to raise an IOError.
> 
> 
> (What were you expecting for "count"?  I see none, just an errno.)
> 
> 
> Note that it *never* returns -1; it returns 0 for successful
> completion for the aiocb, EINPROGRESS if it's still working, and the
> appropriate errno if it failed.

It seems as though it can return -1 if given non-sensical input.  But in
that case, the nicely type-correct thing to do would still be to have
the C binding return a CInt, and wrap that after the call to
throwErrnoIfMinus1 (in this case, `errno' still refers to the global
errno, set to EINVAL).

jcc



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Brandon S. Allbery KF8NH


On 2008 Jul 2, at 2:15, Jonathan Cast wrote:

It seems as though it can return -1 if given non-sensical input.   
But in


The POSIX spec says it returns EINVAL in that case.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Jonathan Cast
On Wed, 2008-07-02 at 02:17 -0400, Brandon S. Allbery KF8NH wrote:
> On 2008 Jul 2, at 2:15, Jonathan Cast wrote:
> 
> > It seems as though it can return -1 if given non-sensical input.   
> > But in
> 
> The POSIX spec says it returns EINVAL in that case.

Are you sure?  A little googling picks up e.g. HP docs [1] that state

RETURN VALUE
If the aiocb is invalid or if no asynchronous I/O operation is enqueued
for the aiocb, aio_error() returns -1 and errno is set to indicate the
error

It may be non-POSIX, but I'd like to see some verbiage for which HP/UX's
behavior isn't the most natural interpretation.

jcc

[1] http://docs.hp.com/en/B9106-90009/aio_error.2.html

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...

2008-07-01 Thread Galchin, Vasili
Thanks, Brandon!! I understand most of what you say but let me ponder!

Kind regards, Vasili

On Wed, Jul 2, 2008 at 1:07 AM, Brandon S. Allbery KF8NH <
[EMAIL PROTECTED]> wrote:

>
> On 2008 Jul 2, at 1:42, Galchin, Vasili wrote:
>
>   errno <- throwErrnoIfMinus1 "aioError" (c_aio_error  p_aiocb)
>
> "ghc" thinks that "Errno" should be an instance of "Num":
>
> System/Posix/Aio.hsc:117:15:
> No instance for (Num Errno)
>
>
> I expect so it can compare it to -1(throwErrnoIfMinusOne).  But if the
> return value is actually an errno and not -1 to indicate error (which it is
> if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway;
> I suspect you want to wrap the return value of c_aio_return (which should be
> IO CInt) in an Errno constructor, then use errnoToIOError if you really want
> to raise an IOError.
>
> (What were you expecting for "count"?  I see none, just an errno.)
>
> Note that it *never* returns -1; it returns 0 for successful completion for
> the aiocb, EINPROGRESS if it's still working, and the appropriate errno if
> it failed.
>
> You might want to decide if you want to use the aio_return style interface
> or something more Haskell-ish before designing this part of the API.  If you
> want to stick close to the C interface:
>
> aioReturn :: AIOCB -> IO (AIOCB, Errno)
> aioReturn aiocb = do
>allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do
>   poke p_aiocb aiocb
>   err <- c_aio_return  p_aiocb
>   aiocb <- peek p_aiocb
>   return (aiocb, Errno err)
> I'd actually consider something more Haskellish, e.g. a variant of StateT
> IO where the state is the aiocb and errno, the errno initialized to
> eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called,
> it can't be called again so return the cached value if needed).
>
> --
> brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
> system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
> electrical and computer engineering, carnegie mellon universityKF8NH
>
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe