Darren Cook wrote:
> I wonder if you had anything to say on how the development was? I'm
> especially interested if you think if there was some aspect of the way
> libego is written that made it either hard work for you, or made it
> inefficient to wrap?

I don't think so, beyond being written in C++ in the first place. C++
code is harder to wrap than C code just because C++ interfaces are that
much richer, and because Pyrex isn't really designed for C++.

(Well, there was one thing: I didn't find a nice way to wrap the
functions that use iostreams in their interfaces. But that's not very
interesting, because those are the text-manipulation bits that you
wouldn't write in C++ if you were making a hybrid program).

A lot of the inefficiency comes because I was aiming for a Python
extension with pretty much the same interface as libego. For real work
it would be better to start with the attitude "let's make a decent
Python extension for working with go boards, and use libego to build
it". I suppose you'd have functions for looping over each point in the
board, for example, which would avoid constructing a silly Python Vertex
object for each point.

A real hybrid program would be more efficient again, because you could
have C++ code implementing exactly what the interpreted code happens to
need, and you could do away with the expectation that you shouldn't be
able to crash the Python interpreter by passing bad parameters to an
extension module. I still suspect that Python would be too slow to use
for anything that happens as frequently as once per playout.


> In notes.txt you say the speed dropped from 70-75 kpps to 43 kpps when
> used in the wrapper (compared to 1 or 2.5 kpps in native python). And
> you say this is due to the overhead of converting and checking
> parameters? If you increase the number of playouts by a factor of 10
> does it close in to 70kpps?

That drop happens because the Python code for running the benchmark
itself is slower than the C++ code for doing so. That is, (I think) we
lose so much speed because each iteration of the Python code in this
loop

    for i in xrange(playout_count):
        working_board = start_board.copy()
        playout = Playout_cls(working_board, first_player)
        status = runner(playout)
        if status == pyego.PLAYOUT_OK:
            wins[working_board.winner()] += 1
        elif status == pyego.PLAYOUT_MERCY:
            wins[working_board.approx_winner()] += 1

takes similar time to the single 9x9 libego playout that it runs.

Increasing the number of playouts doesn't change things. But if I try it
on a 19x19 board the penalty is rather lower, because the C++ code takes
more time.


> I wondered if it might be possible that some compiler optimization got
> missed, or is just not possible, when built as an extension?

The drop from ~75 to ~70 kpps is because of poorer compiler output when
building as an extension (that is: I changed 'always_inline' to plain
'inline' everywhere to get the extension to compile; I presume it would
be possible to put always_inline back and have separate entry points for
the Python code marked plain 'inline', and I should think this would
regain that 7%).

-M-

_______________________________________________
computer-go mailing list
computer-go@computer-go.org
http://www.computer-go.org/mailman/listinfo/computer-go/

Reply via email to