run flags vs active intervals


Larry Gritz <l...@...>
 

Awesome, Chris. Would you believe we were just talking internally about this topic yesterday? We were considering the amount of waste if there were big gaps of "off" points in the middle. But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points). I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?). Ugh, and we may wish to change/add OIIO texture routines that take runflags, too. But your experiment is quite convincing.

What does everybody else think? Chris/Cliff/Alex? (I'm happy to do the coding, but I want consensus because it touches so much.)

-- lg


On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:

Hi all,

I've been looking through the OSL source a little, and I'm interested to see
that you're using runflags for the SIMD state. I know that's a really
conventional solution, but there's an alternative representation which I reckon
is significantly faster, and I wondered if you considered it.

Imagine a SIMD runstate as follows

index: [ 0 1 2 3 4 5 6 7 8 9 ]

flags: [ 0 0 1 1 1 1 0 0 1 0 ]


An alternative to the flags is to represent this state as a list of active
intervals. As a set of active start/stop pairs, the state looks like

active = [ 2 6 8 9 ]

ie,

state: [ 0 0 1 1 1 1 0 0 1 0 ]
^ v ^ v
2 6 8 9

The advantage of doing this is that the inner SIMD loops become tighter since
there's one less test. Instead of

for (int i = 0; i < len; ++i)
{
if (state[i])
do_something(i);
}

we'd have

for (int j = 0; j < nActiveTimes2; j+=2)
{
for (int i = active[j]; i < active[j+1]; ++i)
do_something(i);
}

and the inner loop is now completely coherent.

I can see you have the beginnings of this idea in the current OSL code, since
you pass beginpoint and endpoint along with the runflags everywhere. However,
why not take it to its logical conclusion?

Given that you already have beginpoint and endpoint, the particularly big win
here is when most of the flags are turned on. If do_something() is a simple
arithmetic operation (eg, float addition) the difference between the two
formulations can be a factor of two in speed.


I'm attaching some basic test code which I whipped up. Timings on my core2 duo
with gcc -O3 look like:


All flags on (completely coherent):

run flags: 1.310s
active intervals: 0.690s


Random flags on (completely incoherent):

run flags: 5.440s
active intervals: 3.310s


Alternate flags on (maximum number of active intervals -> worst case):

run flags: 1.500s
active intervals: 2.150s


Thoughts?

~Chris.
<ATT00001..txt><runstate.cpp>
--
Larry Gritz
l...@...


Wormszer <worm...@...>
 

Is there a good resource on this topic? I did some googling and didn't see what i was looking for.

Where is the actual SIMD taking place?
Is the compiler figuring it out from the loop and setting up the correct instructions. Or is it relying on the cpu to recognize consecutive ops with different data, modifying instructions in its pipe by combing instructions into a parallel one.

Or maybe i'm way off.

Thanks,

Jeremy


On Thu, Jan 21, 2010 at 12:16 PM, Larry Gritz <l...@...> wrote:
Awesome, Chris.  Would you believe we were just talking internally about this topic yesterday?  We were considering the amount of waste if there were big gaps of "off" points in the middle.  But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points).  I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?).  Ugh, and we may wish to change/add OIIO texture routines that take runflags, too.  But your experiment is quite convincing.

What does everybody else think?  Chris/Cliff/Alex?  (I'm happy to do the coding, but I want consensus because it touches so much.)

       -- lg


On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:

> Hi all,
>
> I've been looking through the OSL source a little, and I'm interested to see
> that you're using runflags for the SIMD state.  I know that's a really
> conventional solution, but there's an alternative representation which I reckon
> is significantly faster, and I wondered if you considered it.
>
> Imagine a SIMD runstate as follows
>
> index: [ 0  1  2  3  4  5  6  7  8  9 ]
>
> flags: [ 0  0  1  1  1  1  0  0  1  0 ]
>
>
> An alternative to the flags is to represent this state as a list of active
> intervals.  As a set of active start/stop pairs, the state looks like
>
> active = [ 2 6  8 9 ]
>
> ie,
>
> state: [ 0  0  1  1  1  1  0  0  1  0 ]
>               ^           v     ^  v
>               2           6     8  9
>
> The advantage of doing this is that the inner SIMD loops become tighter since
> there's one less test.  Instead of
>
> for (int i = 0; i < len; ++i)
> {
>    if (state[i])
>        do_something(i);
> }
>
> we'd have
>
> for (int j = 0; j < nActiveTimes2; j+=2)
> {
>    for (int i = active[j]; i < active[j+1]; ++i)
>        do_something(i);
> }
>
> and the inner loop is now completely coherent.
>
> I can see you have the beginnings of this idea in the current OSL code, since
> you pass beginpoint and endpoint along with the runflags everywhere.  However,
> why not take it to its logical conclusion?
>
> Given that you already have beginpoint and endpoint, the particularly big win
> here is when most of the flags are turned on.  If do_something() is a simple
> arithmetic operation (eg, float addition) the difference between the two
> formulations can be a factor of two in speed.
>
>
> I'm attaching some basic test code which I whipped up.  Timings on my core2 duo
> with gcc -O3 look like:
>
>
> All flags on (completely coherent):
>
> run flags:        1.310s
> active intervals: 0.690s
>
>
> Random flags on (completely incoherent):
>
> run flags:        5.440s
> active intervals: 3.310s
>
>
> Alternate flags on (maximum number of active intervals -> worst case):
>
> run flags:        1.500s
> active intervals: 2.150s
>
>
> Thoughts?
>
> ~Chris.
> <ATT00001..txt><runstate.cpp>

--
Larry Gritz
l...@...





--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.





Larry Gritz <l...@...>
 

It's not really referring to hardware SIMD, but just that we are shading many points at once, "in lock-step."  In other words, if you had many points to shade, you could do it in this order:

    point 0:
        add
        texture
        assign
    point 1:
        add
        texture
        assign
    ...
    point n:
        add
        texture
        assign

or you could do it in this order:

    add all points on [0,n]
    texture all points on [0,n]
    assign all points on [0,n]

We call the latter "SIMD" (single instruction, multiple data), because each instruction operates on big arrays of data (one value for each point being shaded).

SIMD helps by:

   * increasing interpreter speed, by moving much of the interpreter overhead to "per batch" rather than "per point".
   * improving memory coherence, cache behavior, and allowing hardware SIMD, since it's naturally using "structure-of-array" layout, i.e. it's faster to add contiguous arrays than separate floats in more sparse memory locations.
   * improves texture coherence because you're doing lots of lookups from the same texture on all points at the same time (which are in turn likely to be on the same tiles).




On Jan 21, 2010, at 9:30 AM, Wormszer wrote:

Is there a good resource on this topic? I did some googling and didn't see what i was looking for.

Where is the actual SIMD taking place?
Is the compiler figuring it out from the loop and setting up the correct instructions. Or is it relying on the cpu to recognize consecutive ops with different data, modifying instructions in its pipe by combing instructions into a parallel one.

Or maybe i'm way off.

Thanks,

Jeremy

On Thu, Jan 21, 2010 at 12:16 PM, Larry Gritz <l...@...> wrote:
Awesome, Chris.  Would you believe we were just talking internally about this topic yesterday?  We were considering the amount of waste if there were big gaps of "off" points in the middle.  But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points).  I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?).  Ugh, and we may wish to change/add OIIO texture routines that take runflags, too.  But your experiment is quite convincing.

What does everybody else think?  Chris/Cliff/Alex?  (I'm happy to do the coding, but I want consensus because it touches so much.)

       -- lg


On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:

> Hi all,
>
> I've been looking through the OSL source a little, and I'm interested to see
> that you're using runflags for the SIMD state.  I know that's a really
> conventional solution, but there's an alternative representation which I reckon
> is significantly faster, and I wondered if you considered it.
>
> Imagine a SIMD runstate as follows
>
> index: [ 0  1  2  3  4  5  6  7  8  9 ]
>
> flags: [ 0  0  1  1  1  1  0  0  1  0 ]
>
>
> An alternative to the flags is to represent this state as a list of active
> intervals.  As a set of active start/stop pairs, the state looks like
>
> active = [ 2 6  8 9 ]
>
> ie,
>
> state: [ 0  0  1  1  1  1  0  0  1  0 ]
>               ^           v     ^  v
>               2           6     8  9
>
> The advantage of doing this is that the inner SIMD loops become tighter since
> there's one less test.  Instead of
>
> for (int i = 0; i < len; ++i)
> {
>    if (state[i])
>        do_something(i);
> }
>
> we'd have
>
> for (int j = 0; j < nActiveTimes2; j+=2)
> {
>    for (int i = active[j]; i < active[j+1]; ++i)
>        do_something(i);
> }
>
> and the inner loop is now completely coherent.
>
> I can see you have the beginnings of this idea in the current OSL code, since
> you pass beginpoint and endpoint along with the runflags everywhere.  However,
> why not take it to its logical conclusion?
>
> Given that you already have beginpoint and endpoint, the particularly big win
> here is when most of the flags are turned on.  If do_something() is a simple
> arithmetic operation (eg, float addition) the difference between the two
> formulations can be a factor of two in speed.
>
>
> I'm attaching some basic test code which I whipped up.  Timings on my core2 duo
> with gcc -O3 look like:
>
>
> All flags on (completely coherent):
>
> run flags:        1.310s
> active intervals: 0.690s
>
>
> Random flags on (completely incoherent):
>
> run flags:        5.440s
> active intervals: 3.310s
>
>
> Alternate flags on (maximum number of active intervals -> worst case):
>
> run flags:        1.500s
> active intervals: 2.150s
>
>
> Thoughts?
>
> ~Chris.
> <ATT00001..txt><runstate.cpp>

--
Larry Gritz
l...@...





--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.




<ATT00001..htm>

--
Larry Gritz




Wormszer <worm...@...>
 

Thanks, that makes sense. I know compilers are getting smarter all the time but wasn't sure if they were there yet. The cache and memory coherence makes sense, and then sorting things like that would allow for easier parallel implementations on GPU, etc.

Another quick question what is n, is n the total number of pixels in the image, or i possibly rays? And that's why you have disabled ops, pixels that shader is not applied too?
Is there a good place to look or read about that? Or do i need to dig into the source?

Is it ok to ask these questions in this thread like this or should I be starting a new one? I don't want to fill this thread with off topic information from the original questions? I am somewhat new to this process, and unclear on what is looked down upon.

Thanks
Jeremy


On Thu, Jan 21, 2010 at 12:44 PM, Larry Gritz <l...@...> wrote:
It's not really referring to hardware SIMD, but just that we are shading many points at once, "in lock-step."  In other words, if you had many points to shade, you could do it in this order:

    point 0:
        add
        texture
        assign
    point 1:
        add
        texture
        assign
    ...
    point n:
        add
        texture
        assign

or you could do it in this order:

    add all points on [0,n]
    texture all points on [0,n]
    assign all points on [0,n]

We call the latter "SIMD" (single instruction, multiple data), because each instruction operates on big arrays of data (one value for each point being shaded).

SIMD helps by:

   * increasing interpreter speed, by moving much of the interpreter overhead to "per batch" rather than "per point".
   * improving memory coherence, cache behavior, and allowing hardware SIMD, since it's naturally using "structure-of-array" layout, i.e. it's faster to add contiguous arrays than separate floats in more sparse memory locations.
   * improves texture coherence because you're doing lots of lookups from the same texture on all points at the same time (which are in turn likely to be on the same tiles).




On Jan 21, 2010, at 9:30 AM, Wormszer wrote:

Is there a good resource on this topic? I did some googling and didn't see what i was looking for.

Where is the actual SIMD taking place?
Is the compiler figuring it out from the loop and setting up the correct instructions. Or is it relying on the cpu to recognize consecutive ops with different data, modifying instructions in its pipe by combing instructions into a parallel one.

Or maybe i'm way off.

Thanks,

Jeremy

On Thu, Jan 21, 2010 at 12:16 PM, Larry Gritz <l...@...> wrote:
Awesome, Chris.  Would you believe we were just talking internally about this topic yesterday?  We were considering the amount of waste if there were big gaps of "off" points in the middle.  But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points).  I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?).  Ugh, and we may wish to change/add OIIO texture routines that take runflags, too.  But your experiment is quite convincing.

What does everybody else think?  Chris/Cliff/Alex?  (I'm happy to do the coding, but I want consensus because it touches so much.)

       -- lg


On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:

> Hi all,
>
> I've been looking through the OSL source a little, and I'm interested to see
> that you're using runflags for the SIMD state.  I know that's a really
> conventional solution, but there's an alternative representation which I reckon
> is significantly faster, and I wondered if you considered it.
>
> Imagine a SIMD runstate as follows
>
> index: [ 0  1  2  3  4  5  6  7  8  9 ]
>
> flags: [ 0  0  1  1  1  1  0  0  1  0 ]
>
>
> An alternative to the flags is to represent this state as a list of active
> intervals.  As a set of active start/stop pairs, the state looks like
>
> active = [ 2 6  8 9 ]
>
> ie,
>
> state: [ 0  0  1  1  1  1  0  0  1  0 ]
>               ^           v     ^  v
>               2           6     8  9
>
> The advantage of doing this is that the inner SIMD loops become tighter since
> there's one less test.  Instead of
>
> for (int i = 0; i < len; ++i)
> {
>    if (state[i])
>        do_something(i);
> }
>
> we'd have
>
> for (int j = 0; j < nActiveTimes2; j+=2)
> {
>    for (int i = active[j]; i < active[j+1]; ++i)
>        do_something(i);
> }
>
> and the inner loop is now completely coherent.
>
> I can see you have the beginnings of this idea in the current OSL code, since
> you pass beginpoint and endpoint along with the runflags everywhere.  However,
> why not take it to its logical conclusion?
>
> Given that you already have beginpoint and endpoint, the particularly big win
> here is when most of the flags are turned on.  If do_something() is a simple
> arithmetic operation (eg, float addition) the difference between the two
> formulations can be a factor of two in speed.
>
>
> I'm attaching some basic test code which I whipped up.  Timings on my core2 duo
> with gcc -O3 look like:
>
>
> All flags on (completely coherent):
>
> run flags:        1.310s
> active intervals: 0.690s
>
>
> Random flags on (completely incoherent):
>
> run flags:        5.440s
> active intervals: 3.310s
>
>
> Alternate flags on (maximum number of active intervals -> worst case):
>
> run flags:        1.500s
> active intervals: 2.150s
>
>
> Thoughts?
>
> ~Chris.
> <ATT00001..txt><runstate.cpp>

--
Larry Gritz
l...@...





--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.




<ATT00001..htm>

--
Larry Gritz




--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.



Xavier Ho <con...@...>
 

On Fri, Jan 22, 2010 at 4:15 AM, Wormszer <worm...@...> wrote:
Is it ok to ask these questions in this thread like this or should I be starting a new one? I don't want to fill this thread with off topic information from the original questions? I am somewhat new to this process, and unclear on what is looked down upon.

As a uni student who is keen on the OSL open source release, I'm glad to be reading these discussions - particularly questions and answers. They're the source of knowledge, freely shared insights. It excites the community in its common understanding of this project, and benefits those who, like myself, digest the information that go through mailing lists. Not to mention this is probably archived, and later on searchable if you ever need it again. My opinion is, if it's related, it's probably okay. Unless you intend to start a newer/bigger conversation, there isn't really a need to start a new thread. Having multiple threads on similar topics only make digging information harder, anyhow.

My 2 cp,
Xavier


Christopher <cku...@...>
 

I like this idea too. What we were discussing yesterday was something
like:

index: [ 0 1 2 3 4 5 6 7 8 9 ]
flags: [ 0 0 1 1 1 1 0 0 1 0 ]
active_points: [ 2 3 4 5 8 ]

for (int i = 0; i < num_active; i++)
do_something(active_points[i]);

This would be slightly more efficient if you had a single point active
(or isolated single points), but it requires a lot more indirections
in the common case.

So I'm all in favor of trying this out - though it is a pretty big
overhaul ...

I would maintain these ranges as little int arrays on the stack just
like we maintain the runflags now. The upper bound for the
active_range array size is just npoints (run flags: on off on off on
off ...) - flip any bit and you get fewer "runs".

-Chris

On Jan 21, 9:16 am, Larry Gritz <l...@...> wrote:
Awesome, Chris.  Would you believe we were just talking internally about this topic yesterday?  We were considering the amount of waste if there were big gaps of "off" points in the middle.  But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points).  I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?).  Ugh, and we may wish to change/add OIIO texture routines that take runflags, too.  But your experiment is quite convincing.

What does everybody else think?  Chris/Cliff/Alex?  (I'm happy to do the coding, but I want consensus because it touches so much.)

        -- lg

On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:



Hi all,
I've been looking through the OSL source a little, and I'm interested to see
that you're using runflags for the SIMD state.  I know that's a really
conventional solution, but there's an alternative representation which I reckon
is significantly faster, and I wondered if you considered it.
Imagine a SIMD runstate as follows
index: [ 0  1  2  3  4  5  6  7  8  9 ]
flags: [ 0  0  1  1  1  1  0  0  1  0 ]
An alternative to the flags is to represent this state as a list of active
intervals.  As a set of active start/stop pairs, the state looks like
active = [ 2 6  8 9 ]
ie,
state: [ 0  0  1  1  1  1  0  0  1  0 ]
              ^           v     ^  v
              2           6     8  9
The advantage of doing this is that the inner SIMD loops become tighter since
there's one less test.  Instead of
for (int i = 0; i < len; ++i)
{
   if (state[i])
       do_something(i);
}
we'd have
for (int j = 0; j < nActiveTimes2; j+=2)
{
   for (int i = active[j]; i < active[j+1]; ++i)
       do_something(i);
}
and the inner loop is now completely coherent.
I can see you have the beginnings of this idea in the current OSL code, since
you pass beginpoint and endpoint along with the runflags everywhere.  However,
why not take it to its logical conclusion?
Given that you already have beginpoint and endpoint, the particularly big win
here is when most of the flags are turned on.  If do_something() is a simple
arithmetic operation (eg, float addition) the difference between the two
formulations can be a factor of two in speed.
I'm attaching some basic test code which I whipped up.  Timings on my core2 duo
with gcc -O3 look like:
All flags on (completely coherent):
run flags:        1.310s
active intervals: 0.690s
Random flags on (completely incoherent):
run flags:        5.440s
active intervals: 3.310s
Alternate flags on (maximum number of active intervals -> worst case):
run flags:        1.500s
active intervals: 2.150s
Thoughts?
~Chris.
<ATT00001..txt><runstate.cpp>
--
Larry Gritz
l...@...


Larry Gritz <l...@...>
 

I want to point out that Chris F tested out the "all on", "random on", and "alternating on/off" cases. There's one more case that may be important, which is a few isolated "on" points with big "off" gaps in between -- and in that case, I expect Chris F's solution to perform even better (compared to what we have now) than the other cases.

I'm not looking forward to doing this overhaul (only because it's tedious and extensive, there's nothing hard about it), but I think it's potentially a big win. Thanks, Chris!

-- lg


On Jan 21, 2010, at 10:49 AM, Christopher wrote:

I like this idea too. What we were discussing yesterday was something
like:

index: [ 0 1 2 3 4 5 6 7 8 9 ]
flags: [ 0 0 1 1 1 1 0 0 1 0 ]
active_points: [ 2 3 4 5 8 ]

for (int i = 0; i < num_active; i++)
do_something(active_points[i]);

This would be slightly more efficient if you had a single point active
(or isolated single points), but it requires a lot more indirections
in the common case.

So I'm all in favor of trying this out - though it is a pretty big
overhaul ...

I would maintain these ranges as little int arrays on the stack just
like we maintain the runflags now. The upper bound for the
active_range array size is just npoints (run flags: on off on off on
off ...) - flip any bit and you get fewer "runs".

-Chris


On Jan 21, 9:16 am, Larry Gritz <l...@...> wrote:
Awesome, Chris. Would you believe we were just talking internally about this topic yesterday? We were considering the amount of waste if there were big gaps of "off" points in the middle. But I think your solution is quite a bit more elegant than what we were discussing (a list of "on" points). I like how it devolves into (begin,end] for the common case of all points on.

It's a pretty big overhaul, touches every shadeop and a lot of templates, and the call signatures have to be changed (to what, exactly? passing a std::vector<int>& ? or a combo of int *begend and int segments?). Ugh, and we may wish to change/add OIIO texture routines that take runflags, too. But your experiment is quite convincing.

What does everybody else think? Chris/Cliff/Alex? (I'm happy to do the coding, but I want consensus because it touches so much.)

-- lg

On Jan 21, 2010, at 8:21 AM, Chris Foster wrote:



Hi all,
I've been looking through the OSL source a little, and I'm interested to see
that you're using runflags for the SIMD state. I know that's a really
conventional solution, but there's an alternative representation which I reckon
is significantly faster, and I wondered if you considered it.
Imagine a SIMD runstate as follows
index: [ 0 1 2 3 4 5 6 7 8 9 ]
flags: [ 0 0 1 1 1 1 0 0 1 0 ]
An alternative to the flags is to represent this state as a list of active
intervals. As a set of active start/stop pairs, the state looks like
active = [ 2 6 8 9 ]
ie,
state: [ 0 0 1 1 1 1 0 0 1 0 ]
^ v ^ v
2 6 8 9
The advantage of doing this is that the inner SIMD loops become tighter since
there's one less test. Instead of
for (int i = 0; i < len; ++i)
{
if (state[i])
do_something(i);
}
we'd have
for (int j = 0; j < nActiveTimes2; j+=2)
{
for (int i = active[j]; i < active[j+1]; ++i)
do_something(i);
}
and the inner loop is now completely coherent.
I can see you have the beginnings of this idea in the current OSL code, since
you pass beginpoint and endpoint along with the runflags everywhere. However,
why not take it to its logical conclusion?
Given that you already have beginpoint and endpoint, the particularly big win
here is when most of the flags are turned on. If do_something() is a simple
arithmetic operation (eg, float addition) the difference between the two
formulations can be a factor of two in speed.
I'm attaching some basic test code which I whipped up. Timings on my core2 duo
with gcc -O3 look like:
All flags on (completely coherent):
run flags: 1.310s
active intervals: 0.690s
Random flags on (completely incoherent):
run flags: 5.440s
active intervals: 3.310s
Alternate flags on (maximum number of active intervals -> worst case):
run flags: 1.500s
active intervals: 2.150s
Thoughts?
~Chris.
<ATT00001..txt><runstate.cpp>
--
Larry Gritz
l...@...
<ATT00001..txt>
--
Larry Gritz
l...@...


Chris Foster <chri...@...>
 

On Fri, Jan 22, 2010 at 4:56 AM, Larry Gritz <l...@...> wrote:
I want to point out that Chris F tested out the "all on", "random on", and
"alternating on/off" cases.  There's one more case that may be important,
which is a few isolated "on" points with big "off" gaps in between -- and in
that case, I expect Chris F's solution to perform even better (compared to
what we have now) than the other cases.
Right, here's the initialization code for some sparse on-states:

// Four isolated flags turned on.
std::fill((Runflag*)r, r+len, (Runflag)Runflag_Off);
r[0] = r[50] = r[100] = r[150] = Runflag_On;

results for this sparse case:

run flags: 1.710s
active intervals: 0.100s

Of course in this case, the run flags completely fail to captialize on the
fact that most of the shading elements are turned off, so the active intervals
formulation thrashes it. Out of curiosity, I've also implemented the direct
indexing array Chris K suggested (code attached, see the function
addIndexed() ):

active index: 0.050s

as expected, blazingly fast here!


Here's the rest of the benchmarks redone with the active indexing method added:


All flags on (completely coherent):

run flags: 1.310s
active intervals: 0.690s
active index: 1.330s


Random flags on (completely incoherent):

run flags: 5.440s
active intervals: 3.310s
active index: 0.760s


Alternate flags on (maximum number of active intervals):

run flags: 1.500s
active intervals: 2.150s
active index: 0.710s


The results are quite interesting. They suggest that active indexing is likely
to be faster for highly incoherent data, but that active intervals is the clear
winnier when all your flags are on.

The random flags benchmark is particularly interesting to me because the active
intervals formulation does a lot worse than the active index in this case.


As for the implementation, you can potentially have the ability to change
between any of these run state implementations if you introduce an iterator
abstraction. The tricky thing seems to be making sure the abstraction is
getting optimized as efficiently as the plain loops.

Here's my crack at an active intervals iterator class, but alas, the benchmarks
show that this gives a time of 1.170s for the all-on case compared to 0.68s for
the loop-based implementation.


class RunStateIter
{
private:
const int* m_intervals; ///< active intervals
const int* m_intervalsEnd; ///< end of active intervals
int m_currEnd; ///< end of current interval
int m_idx; ///< current index
public:
RunStateIter(const int* intervals, int nIntervals)
: m_intervals(intervals),
m_intervalsEnd(intervals + 2*nIntervals),
m_currEnd(nIntervals ? intervals[1] : 0),
m_idx(nIntervals ? intervals[0] : 0)
{ }

RunStateIter& operator++()
{
++m_idx;
if (m_idx >= m_currEnd) {
m_intervals += 2;
if (m_intervals < m_intervalsEnd) {
m_idx = m_intervals[0];
m_currEnd = m_intervals[1];
}
}
return *this;
}

bool valid() { return m_idx < m_currEnd; }

int operator*() { return m_idx; }
};


Now why is this? The above is essentially the loop-based code but unravelled
into an iterator. I had to look at the assembly code to find out, and it turns
out that the compiler is optimizing addIntervals() using hardware SIMD! (I spy
lots of movlps and an addps in there.)

Ack! I hadn't expected that. I was imagining that the efficiency gains in the
all-on case came from improving branch prediciton or some such. Oops :-)
Using the flag -fno-tree-vectorize causes performance of the active intervals
code in the all-on case to devolve to 1.33s, just the same as the runflags
code.

So, this changes a few things, because (1) I guess there's not that many
operations which the compiler can produce hardware SIMD code for, so the
efficiency gains I've just shown may evaporate if user-defined types come into
play and (2) the compiler (g++) seems to have trouble producing hardware SIMD
code when an iterator abstraction is involved. That's a pity because using an
iterator would let you reimplement this stuff once and decide what the iterator
implementation should be later, based on real benchmarks.

Hum, so suddenly the way forward doesn't seem quite so clear anymore. The
active index method starts to look very attractive if we discount hardware
vectorization.

~Chris.


Wormszer <worm...@...>
 

That's interesting, it kind of relates to my original question if the compiler was able to apply SIMD operations to the loop.
When you disabled vectorization did it effect the active index case?

Are those numbers taking into account the setup time to create either the active index or the intervals? Or is it basically the same for each method?

The iterator idea crossed my mind too but I too wouldn't of expected it to have such a performance hit either. I guess it prevents the compiler from unrolling the loop?
I wonder if the way you use the iterator is having an effect, where a for(begin, end, ++) implementation etc, if the compiler would do something different.

It looks like active index is the way to go, i wonder why it doesn't perform as well on the full range, is it because of the indirection that the compiler won't vectorize it? That the memory addresses may not be consecutive?

If the two methods perform well under different conditions is there enough of a benefit to say implement both, active intervals/indexs? Or a hybrid,  Active index, and if the # of index's == N, then its all on and could just do a loop without indirection and use a vectorized code path.

Is there enough coherence between frame to frame, execution to execution, that you could possibly score the run and use that method the next time?
Sort of like branch prediction, have some method to measure the coherence or incoherence of the current run to predict the next, even occasionally.


Jeremy


On Thu, Jan 21, 2010 at 8:36 PM, Chris Foster <chri...@...> wrote:
On Fri, Jan 22, 2010 at 4:56 AM, Larry Gritz <l...@...> wrote:
> I want to point out that Chris F tested out the "all on", "random on", and
> "alternating on/off" cases.  There's one more case that may be important,
> which is a few isolated "on" points with big "off" gaps in between -- and in
> that case, I expect Chris F's solution to perform even better (compared to
> what we have now) than the other cases.

Right, here's the initialization code for some sparse on-states:

   // Four isolated flags turned on.
   std::fill((Runflag*)r, r+len, (Runflag)Runflag_Off);
   r[0] = r[50] = r[100] = r[150] = Runflag_On;

results for this sparse case:

run flags:        1.710s
active intervals: 0.100s

Of course in this case, the run flags completely fail to captialize on the
fact that most of the shading elements are turned off, so the active intervals
formulation thrashes it.  Out of curiosity, I've also implemented the direct
indexing array Chris K suggested (code attached, see the function
addIndexed() ):

active index:     0.050s

as expected, blazingly fast here!


Here's the rest of the benchmarks redone with the active indexing method added:


All flags on (completely coherent):

run flags:        1.310s
active intervals: 0.690s
active index:     1.330s


Random flags on (completely incoherent):

run flags:        5.440s
active intervals: 3.310s
active index:     0.760s


Alternate flags on (maximum number of active intervals):

run flags:        1.500s
active intervals: 2.150s
active index:     0.710s


The results are quite interesting.  They suggest that active indexing is likely
to be faster for highly incoherent data, but that active intervals is the clear
winnier when all your flags are on.

The random flags benchmark is particularly interesting to me because the active
intervals formulation does a lot worse than the active index in this case.


As for the implementation, you can potentially have the ability to change
between any of these run state implementations if you introduce an iterator
abstraction.  The tricky thing seems to be making sure the abstraction is
getting optimized as efficiently as the plain loops.

Here's my crack at an active intervals iterator class, but alas, the benchmarks
show that this gives a time of 1.170s for the all-on case compared to 0.68s for
the loop-based implementation.


class RunStateIter
{
   private:
       const int* m_intervals; ///< active intervals
       const int* m_intervalsEnd; ///< end of active intervals
       int m_currEnd;          ///< end of current interval
       int m_idx;              ///< current index
   public:
       RunStateIter(const int* intervals, int nIntervals)
           : m_intervals(intervals),
           m_intervalsEnd(intervals + 2*nIntervals),
           m_currEnd(nIntervals ? intervals[1] : 0),
           m_idx(nIntervals ? intervals[0] : 0)
       { }

       RunStateIter& operator++()
       {
           ++m_idx;
           if (m_idx >= m_currEnd) {
               m_intervals += 2;
               if (m_intervals < m_intervalsEnd) {
                   m_idx = m_intervals[0];
                   m_currEnd = m_intervals[1];
               }
           }
           return *this;
       }

       bool valid() { return m_idx < m_currEnd; }

       int operator*() { return m_idx; }
};


Now why is this?  The above is essentially the loop-based code but unravelled
into an iterator.  I had to look at the assembly code to find out, and it turns
out that the compiler is optimizing addIntervals() using hardware SIMD!  (I spy
lots of movlps and an addps in there.)

Ack!  I hadn't expected that.  I was imagining that the efficiency gains in the
all-on case came from improving branch prediciton or some such.  Oops :-)
Using the flag -fno-tree-vectorize causes performance of the active intervals
code in the all-on case to devolve to 1.33s, just the same as the runflags
code.

So, this changes a few things, because (1) I guess there's not that many
operations which the compiler can produce hardware SIMD code for, so the
efficiency gains I've just shown may evaporate if user-defined types come into
play and (2) the compiler (g++) seems to have trouble producing hardware SIMD
code when an iterator abstraction is involved.  That's a pity because using an
iterator would let you reimplement this stuff once and decide what the iterator
implementation should be later, based on real benchmarks.

Hum, so suddenly the way forward doesn't seem quite so clear anymore.  The
active index method starts to look very attractive if we discount hardware
vectorization.

~Chris.

--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.



Chris Foster <chri...@...>
 

On Fri, Jan 22, 2010 at 5:22 PM, Wormszer <worm...@...> wrote:
That's interesting, it kind of relates to my original question if the
compiler was able to apply SIMD operations to the loop.
When you disabled vectorization did it effect the active index case?
No, the active index case isn't vectorized by the compiler anyway.

Are those numbers taking into account the setup time to create either the
active index or the intervals?
No. In a SIMD shader machine I generally expect that creating the runstate
representation (whatever it may be) from the results of a conditional is going
to be a relatively small proportion of the total runtime.

The iterator idea crossed my mind too but I too wouldn't of expected it to
have such a performance hit either. I guess it prevents the compiler from
unrolling the loop?
Not unrolling, vectorizing - the way I wrote the iterator appears to prevent
the compiler vectorizing the loop using SSE.

I wonder if the way you use the iterator is having an effect, where a
for(begin, end, ++) implementation etc, if the compiler would do something
different.
I don't know. I know nothing about how gcc's tree vectorizer works. If it's
enabled by a heuristic whenever it sees special "simple" uses of the for loop,
then any iterator abstraction is unlikely to work.

It looks like active index is the way to go,
If hardware (SSE) vectorization isn't going to be on the cards for most
operations, I think the active index method is looking like a winner.
Generally speaking it seems to have more reliable performance characteristics,
especially in the face of incoherence.

i wonder why it doesn't perform
as well on the full range, is it because of the indirection that the
compiler won't vectorize it? That the memory addresses may not be
consecutive?
Yes, I think that's the reason.

If the two methods perform well under different conditions is there enough
of a benefit to say implement both, active intervals/indexs? Or a hybrid,
Active index, and if the # of index's == N, then its all on and could just
do a loop without indirection and use a vectorized code path.
I considered something like this too. IMHO, making things this complex
requires that the SIMD state iteration should be abstracted, but an iterator
abstraction isn't appropriate in that case.

Is there enough coherence between frame to frame, execution to execution,
that you could possibly score the run and use that method the next time?
Sort of like branch prediction, have some method to measure the coherence or
incoherence of the current run to predict the next, even occasionally.
That doesn't sound like it would help to me ;-) You need to modify the
runstate at every conditional branch anyway, so it's possible to analyse it for
coherence during modification, if necessary.

~Chris.


Wormszer <worm...@...>
 

 
Not unrolling, vectorizing - the way I wrote the iterator appears to prevent
the compiler vectorizing the loop using SSE.

I guess i was thinking of the vectorization being a type of unrolling, not really in the correct sense i guess.
Where it was expanding it by say by 4 or how ever wide the vector operator is, reducing the number of iterations total.
On the add case i was assuming it would vectorize something like  i ,i+1, i+2, i+3.

If hardware (SSE) vectorization isn't going to be on the cards for most
operations, I think the active index method is looking like a winner.
Generally speaking it seems to have more reliable performance characteristics,
especially in the face of incoherence.

As for this and the rest, I don't know enough about the system yet and how it actually works. I was basing it more on your test code and some of the earlier discussion on SIMD shaders.
After looking at your numbers more if the only case that performed better was the all on, because of the vectorization. Then monitoring and predicting wouldn't help.
Because it would just be a simple check # = N. And from your example i was thinking might have two code paths.
So for your add it would be like

if(nActive==nTotal)  //vectorized path
    for (int j = 0; j < nActive; ++j) {
        c[j] = a[j] + b[j];
    }
else //non-vectorized path
    for (int j = 0; j < nActive; ++j) {
        int i = activeIndex[j];
        c[i] = a[i] + b[i];
    }
In a case where the operator couldn't vectorize etc, you would only need the one option.

But things probably are not that simple and im sure there is a lot more going on that I am missing.

Jeremy

On Fri, Jan 22, 2010 at 10:32 PM, Chris Foster <chri...@...> wrote:
On Fri, Jan 22, 2010 at 5:22 PM, Wormszer <worm...@...> wrote:
> That's interesting, it kind of relates to my original question if the
> compiler was able to apply SIMD operations to the loop.
> When you disabled vectorization did it effect the active index case?

No, the active index case isn't vectorized by the compiler anyway.

> Are those numbers taking into account the setup time to create either the
> active index or the intervals?

No.  In a SIMD shader machine I generally expect that creating the runstate
representation (whatever it may be) from the results of a conditional is going
to be a relatively small proportion of the total runtime.

> The iterator idea crossed my mind too but I too wouldn't of expected it to
> have such a performance hit either. I guess it prevents the compiler from
> unrolling the loop?

Not unrolling, vectorizing - the way I wrote the iterator appears to prevent
the compiler vectorizing the loop using SSE.

> I wonder if the way you use the iterator is having an effect, where a
> for(begin, end, ++) implementation etc, if the compiler would do something
> different.

I don't know.  I know nothing about how gcc's tree vectorizer works.  If it's
enabled by a heuristic whenever it sees special "simple" uses of the for loop,
then any iterator abstraction is unlikely to work.

> It looks like active index is the way to go,

If hardware (SSE) vectorization isn't going to be on the cards for most
operations, I think the active index method is looking like a winner.
Generally speaking it seems to have more reliable performance characteristics,
especially in the face of incoherence.

> i wonder why it doesn't perform
> as well on the full range, is it because of the indirection that the
> compiler won't vectorize it? That the memory addresses may not be
> consecutive?

Yes, I think that's the reason.

> If the two methods perform well under different conditions is there enough
> of a benefit to say implement both, active intervals/indexs? Or a hybrid,
> Active index, and if the # of index's == N, then its all on and could just
> do a loop without indirection and use a vectorized code path.

I considered something like this too.  IMHO, making things this complex
requires that the SIMD state iteration should be abstracted, but an iterator
abstraction isn't appropriate in that case.

> Is there enough coherence between frame to frame, execution to execution,
> that you could possibly score the run and use that method the next time?
> Sort of like branch prediction, have some method to measure the coherence or
> incoherence of the current run to predict the next, even occasionally.

That doesn't sound like it would help to me ;-)  You need to modify the
runstate at every conditional branch anyway, so it's possible to analyse it for
coherence during modification, if necessary.

~Chris.

--
You received this message because you are subscribed to the Google Groups "OSL Developers" group.
To post to this group, send email to osl...@....
To unsubscribe from this group, send email to osl...@....
For more options, visit this group at http://groups.google.com/group/osl-dev?hl=en.



Chris Foster <chri...@...>
 

On Sat, Jan 23, 2010 at 2:19 PM, Wormszer <worm...@...> wrote:


Not unrolling, vectorizing - the way I wrote the iterator appears to
prevent
the compiler vectorizing the loop using SSE.
I guess i was thinking of the vectorization being a type of unrolling, not
really in the correct sense i guess.
Fair enough. Vectorization does imply unrolling the loop (by a factor of
4 for SSE), though loop unrolling can sometimes be a useful optimization
without hardware vectorization.

The active index idea does permit loop unrolling, but not necessarily
vectorization.

If hardware (SSE) vectorization isn't going to be on the cards for most
operations, I think the active index method is looking like a winner.
Generally speaking it seems to have more reliable performance
characteristics,
especially in the face of incoherence.
As for this and the rest, I don't know enough about the system yet and how
it actually works. I was basing it more on your test code and some of the
earlier discussion on SIMD shaders.
After looking at your numbers more if the only case that performed better
was the all on, because of the vectorization. Then monitoring and predicting
wouldn't help.
Because it would just be a simple check # = N. And from your example i was
thinking might have two code paths.
So for your add it would be like

if(nActive==nTotal)  //vectorized path
    for (int j = 0; j < nActive; ++j) {
        c[j] = a[j] + b[j];
    }
else //non-vectorized path
    for (int j = 0; j < nActive; ++j) {
        int i = activeIndex[j];
        c[i] = a[i] + b[i];
    }
Yeah. TBH I haven't studied the code enough to know whether the
vectorized path can be realized using the OSL data structures. If the
arrays are actually given as VaryingRefs then any vectorization attempt
is likely to be dead in the water since VaryingRef has a stride which is
determined at runtime.

~Chris


Larry Gritz <l...@...>
 

OK, I've done some really interesting investigation the runflags issue. Chris Foster was very inspiring with his test program and span idea (which we've been debating versus Chris Kulla's similar "index" idea). But I felt there were two problems with Chris F's program in terms of making a final decision: (1) his test loops did not actually resemble the inside of our shadeops, particularly in our use of VaryingRef and the integer ops it uses to control the stepping, which also can't be known at compile time; (2) he tested a few different runflag scenarios (all-on, every-other-on, and random), but I didn't feel like we really knew what would be typical runflags "in the wild".

So, the first step was that I modified the shading system to check after every instruction, and dump the runflags once every <very large prime> instructions (not perfect, but supposed to make it so it's not likely to keep sampling in the same shader or at the same instruction). I did this for a production test frame that we are using as a benchmark, so it's "real" full production shaders on show assets.

I ended up sampling 4508 run states, which I then collated, sorted, and counted, and ended up with 198 unique run states (remember, to keep the data sets reasonable, these are *sampled*, not a comprehensive set of all run states it ever saw).

Below is the list, one runflag per "line", sorted from most-frequently-seen to least-frequently-seen. The first column is the number of times that run state was found. I'm putting it inline below as well as attaching it (to preserve the original line breaks that separate run states).

The "all on" sets are generally from batches of primary rays that coherently hit objects. The few "big spans of 1" ones are primaries from pixels that were split between more than one object, and conditional states from primaries. The vast number of very sparse 1's in seas of 0's are from secondary rays, which our renderer creates batches from, though it can only shade hits together if they hit objects with the same shaders. The most common run state is a single "1", which is a from a secondary ray batch of which only one ray hit a particular object. Our renderer adjusts the offsets so that sparse secondary batches always begin and end with a point "on".

Enjoy. In follow-up emails, I'll discuss what I did with those runflags next.

---

count run state
----- -----------
4285 rf 1
9 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
5 rf 1 0 0 1
4 rf 1 1
3 rf 1 0 0 0 1
3 rf 1 0 0 0 0 0 0 0 1
2 rf 1 0 1
2 rf 1 0 0 1 0 0 0 0 0 1
2 rf 1 0 0 0 0 1
2 rf 1 0 0 0 0 0 1
2 rf 1 0 0 0 0 0 0 0 0 0 0 1
2 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
2 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 1 1 1 1 1 1
1 rf 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 1
1 rf 1 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 1
1 rf 1 1 1 0 1
1 rf 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 1
1 rf 1 1 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1
1 rf 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1
1 rf 1 1 1
1 rf 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 rf 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 1 1 1 0 0 1 1
1 rf 1 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 1 1 0 1 0 0 1 1
1 rf 1 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
1 rf 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1
1 rf 1 1 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1
1 rf 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 1 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1
1 rf 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1
1 rf 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 1 0 0 1 0 0 0 0 1
1 rf 1 1 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1
1 rf 1 1 0 0 1
1 rf 1 1 0 0 0 1 1 0 0 1 1 1 0 0 0 1
1 rf 1 1 0 0 0 1
1 rf 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1
1 rf 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1
1 rf 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 1
1 rf 1 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1
1 rf 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1
1 rf 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1
1 rf 1 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1
1 rf 1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 1
1 rf 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 0 1 0 1 1
1 rf 1 0 1 1 0 0 0 0 0 0 1
1 rf 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 1 0 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 0 0 0 1 1 1 1 0 1 1 0 1 1 1 0 1
1 rf 1 0 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1
1 rf 1 0 1 0 1 0 0 1
1 rf 1 0 1 0 1 0 0 0 0 0 1 0 1 1
1 rf 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 1 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 1 0 1
1 rf 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 1 0 0 0 0 1
1 rf 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 1
1 rf 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1
1 rf 1 0 0 1 1 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 1 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1
1 rf 1 0 0 1 1
1 rf 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1
1 rf 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1
1 rf 1 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 1 0 1
1 rf 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 1
1 rf 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 0 1
1 rf 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 1 1
1 rf 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 1 1
1 rf 1 0 0 0 1 1
1 rf 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1
1 rf 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1
1 rf 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
1 rf 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 1 1 1
1 rf 1 0 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1
1 rf 1 0 0 0 0 1 0 1 0 0 1
1 rf 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1
1 rf 1 0 0 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 1 1 1 1
1 rf 1 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1
1 rf 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1
1 rf 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1
1 rf 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 1 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 0 0 0 1 0 0 0 1 0 0 0 1
1 rf 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 rf 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
1 rf 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1


--
Larry Gritz
l...@...


Larry Gritz <l...@...>
 

Next installment of "everything you wanted to know about runflags but were afraid to ask."

So after sampling representative runflags from a frame with production shaders and assets, next I wrote a test program. I started with Chris F's, but I think by the end there wasn't any of his left. My test differs from Chris' in two ways: (1) the loops have been rewritten to use VaryingRef and to add Vec3's, so it a little more closely resembles a typical math shadeop; (2) it runs the test for each of a large set of runflags, which are read from an input file. (That input file is, of course, a slightly modified version of the sampled rf states I mailed earlier -- no frequency count.)

For each of the run state samples, it runs 50,000,000 times for each of runflags, Chris F's spans, and Chris K's indices.

I won't keep you in suspense. Here are the results. Times are all in seconds, single threaded, compiled with "g++ -O3". (Test program and input data set also attached.) I'll discuss in a follow-up email.

Don't just read the first few, there are interesting results at the end, too.


---

runflags 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 14 15 35 36 50 51 145 146
indices 14 35 50 145

runflags: 12.01
spans: 1.72
indices: 1.34


runflags 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
span 7 8 17 18 20 21 34 37 47 48 51 52 54 55 82 83 106 108 109 110 115 116 117 118 132 133 134 135 175 176 181 182 189 190 194 195 206 207 208 209 210 211 215 217 227 228 237 238 242 243 248 249
indices 7 17 20 34 35 36 47 51 54 82 106 107 109 115 117 132 134 175 181 189 194 206 208 210 215 216 227 237 242 248

runflags: 36.03
spans: 9.52
indices: 6.53


runflags 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 4 5 21 22 37 38
indices 4 21 37

runflags: 4.72
spans: 1.41
indices: 1.17


runflags 0 0 0 1 0 0 0 1 0 0 0 1
span 3 4 7 8 11 12
indices 3 7 11

runflags: 1.28
spans: 1.41
indices: 1.16


runflags 1
span 0 1
indices 0

runflags: 0.68
spans: 0.84
indices: 0.75


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 156 157
indices 0 156

runflags: 11.16
spans: 1.11
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 93 95 102 103 146 147 191 192
indices 0 93 94 102 146 191

runflags: 18.31
spans: 2.15
indices: 1.72


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 92 93 104 105 178 179
indices 0 92 104 178

runflags: 14.80
spans: 1.72
indices: 1.34


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 90 91
indices 0 90

runflags: 7.24
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 66 67 143 144
indices 0 66 143

runflags: 11.35
spans: 1.41
indices: 1.17


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 64 65
indices 0 64

runflags: 5.21
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 56 57 88 89 100 101 122 123 131 132 157 158 216 217
indices 0 56 88 100 122 131 157 216

runflags: 20.54
spans: 2.91
indices: 2.12


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 55 56 76 77
indices 0 55 76

runflags: 7.60
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 54 55
indices 0 54

runflags: 4.59
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
span 0 1 54 56 71 72 149 151
indices 0 54 55 71 149 150

runflags: 13.99
spans: 2.01
indices: 1.72


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 53 54
indices 0 53

runflags: 4.51
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 53 54 73 74
indices 0 53 73

runflags: 7.46
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 52 53
indices 0 52

runflags: 4.46
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 50 51
indices 0 50

runflags: 4.29
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 48 50 66 69 85 86 129 132 146 148 164 165
indices 0 48 49 66 67 68 85 129 130 131 146 147 164

runflags: 17.99
spans: 4.13
indices: 3.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 47 48
indices 0 47

runflags: 4.15
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 47 48 65 66
indices 0 47 65

runflags: 7.09
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
span 0 1 47 48 51 52
indices 0 47 51

runflags: 6.64
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
span 0 1 36 37 65 66 108 109 129 131 147 148 152 153 168 169 177 178 180 181 196 197 225 226 229 230
indices 0 36 65 108 129 130 147 152 168 177 180 196 225 229

runflags: 26.13
spans: 4.69
indices: 3.33


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 34 35
indices 0 34

runflags: 3.59
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 33 34 81 82
indices 0 33 81

runflags: 8.03
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 33 34 45 46 50 51 53 54 67 69 115 116 128 129 150 151
indices 0 33 45 50 53 67 68 115 128 150

runflags: 16.97
spans: 3.32
indices: 2.54


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 31 32
indices 0 31

runflags: 3.36
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 30 31
indices 0 30

runflags: 3.35
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
span 0 1 30 31 32 33
indices 0 30 32

runflags: 3.88
spans: 1.41
indices: 1.17


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 29 30
indices 0 29

runflags: 3.01
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 29 30 67 68 133 134 136 137 160 161 172 173 207 208 224 225 235 236 246 247
indices 0 29 67 133 136 160 172 207 224 235 246

runflags: 25.92
spans: 3.86
indices: 2.76


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 28 29
indices 0 28

runflags: 2.93
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 28 29 82 83 192 193
indices 0 28 82 192

runflags: 17.65
spans: 1.73
indices: 1.33


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1
span 0 1 28 29 67 68 73 74 80 81 98 99 125 126 143 145 150 151 152 154 186 187 198 199 206 207 217 218 224 225 228 229 234 235 239 242
indices 0 28 67 73 80 98 125 143 144 150 152 153 186 198 206 217 224 228 234 239 240 241

runflags: 30.53
spans: 7.85
indices: 6.17


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
span 0 1 28 29 32 33
indices 0 28 32

runflags: 4.93
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
span 0 1 27 28 47 48 58 59 60 61 77 79 94 95 111 113 118 119 145 146 149 150 162 164
indices 0 27 47 58 60 77 78 94 111 112 118 145 149 162 163

runflags: 21.31
spans: 5.07
indices: 3.57


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
span 0 1 27 28 31 32
indices 0 27 31

runflags: 4.82
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1
span 0 1 26 27 33 35
indices 0 26 33 34

runflags: 5.12
spans: 1.59
indices: 1.33


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 25 26
indices 0 25

runflags: 2.77
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 25 26 84 85
indices 0 25 84

runflags: 8.12
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 24 25 36 37
indices 0 24 36

runflags: 4.86
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 24 25 35 36 37 38 40 41 42 43 55 56
indices 0 24 35 37 40 42 55

runflags: 7.08
spans: 2.61
indices: 1.96


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1
span 0 1 23 24 34 35 37 38
indices 0 23 34 37

runflags: 4.89
spans: 1.75
indices: 1.38


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 23 24 29 30 40 41
indices 0 23 29 40

runflags: 5.42
spans: 1.72
indices: 1.34


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 23 25 32 33 36 37 44 45 56 57
indices 0 23 24 32 36 44 56

runflags: 9.27
spans: 2.64
indices: 1.95


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 22 23
indices 0 22

runflags: 2.56
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 21 22
indices 0 21

runflags: 2.46
spans: 1.10
indices: 0.92


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 20 21 31 32
indices 0 20 31

runflags: 4.55
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
span 0 1 20 21 28 29
indices 0 20 28

runflags: 4.35
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 19 20
indices 0 19

runflags: 2.45
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
span 0 1 19 20 21 22 23 24 32 33 52 53 56 57 65 66 80 81 87 89 105 106 119 120 128 129 148 149 176 178 183 184 187 188 193 194 199 200 203 204 212 213 219 220 233 235
indices 0 19 21 23 32 52 56 65 80 87 88 105 119 128 148 176 177 183 187 193 199 203 212 219 233 234

runflags: 33.48
spans: 8.60
indices: 5.71


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1
span 0 1 19 21 57 58 59 60 66 67
indices 0 19 20 57 59 66

runflags: 8.06
spans: 2.15
indices: 1.73


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 18 19
indices 0 18

runflags: 2.36
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 17 18 49 50
indices 0 17 49

runflags: 5.85
spans: 1.41
indices: 1.17


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1
span 0 1 17 18 33 34 48 49 64 65 70 71 72 73 85 87 88 89 98 99
indices 0 17 33 48 64 70 72 85 86 88 98

runflags: 13.74
spans: 3.61
indices: 2.76


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 17 18 32 33 49 50 67 68 79 80
indices 0 17 32 49 67 79

runflags: 10.14
spans: 2.22
indices: 1.79


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 16 17
indices 0 16

runflags: 2.42
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 15 16
indices 0 15

runflags: 2.11
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1
span 0 1 15 16 32 34 64 65 94 96 97 98 108 109 124 125 128 129 143 144 154 155 156 158 173 175 188 189 192 193 202 203 205 209 216 219 221 222 223 226 232 233 236 238 239 240 241 242
indices 0 15 32 33 64 94 95 97 108 124 128 143 154 156 157 173 174 188 192 202 205 206 207 208 216 217 218 221 223 224 225 232 236 237 239 241

runflags: 37.51
spans: 13.81
indices: 7.69


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 14 15 30 31
indices 0 14 30

runflags: 4.24
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 13 14
indices 0 13

runflags: 1.96
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
span 0 1 13 14 20 21
indices 0 13 20

runflags: 3.81
spans: 1.41
indices: 1.17


runflags 1 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 12 13
indices 0 12

runflags: 1.93
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 12 13 30 31
indices 0 12 30

runflags: 4.48
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1
span 0 1 12 13 22 23 43 44 46 47 54 55
indices 0 12 22 43 46 54

runflags: 8.07
spans: 2.22
indices: 1.72


runflags 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1
span 0 1 12 13 16 17 20 21 25 27 29 30 32 33 39 40
indices 0 12 16 20 25 26 29 32 39

runflags: 8.46
spans: 3.21
indices: 2.37


runflags 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1
span 0 1 12 14 15 16 19 20 33 34 56 57 74 75 79 80 81 82 84 85 86 87 94 95
indices 0 12 13 15 19 33 56 74 79 81 84 86 94

runflags: 14.83
spans: 4.30
indices: 3.17


runflags 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 11 12
indices 0 11

runflags: 2.02
spans: 1.14
indices: 0.96


runflags 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
span 0 1 11 12 67 68 79 80 82 83
indices 0 11 67 79 82

runflags: 8.41
spans: 1.99
indices: 1.54


runflags 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 11 12 57 59 60 61 74 75 107 108 112 113 122 123 124 125 136 137 138 139 141 142 152 153 170 171
indices 0 11 57 58 60 74 107 112 122 124 136 138 141 152 170

runflags: 21.09
spans: 4.79
indices: 3.57


runflags 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1
span 0 1 11 12 17 18 26 27 30 31 48 49 59 60 63 65
indices 0 11 17 26 30 48 59 63 64

runflags: 10.78
spans: 3.05
indices: 2.37


runflags 1 0 0 0 0 0 0 0 0 0 1
span 0 1 10 11
indices 0 10

runflags: 1.76
spans: 1.11
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 10 11 48 49 98 99 123 124 136 137 145 146 159 160 185 186 192 193 197 198 222 223
indices 0 10 48 98 123 136 145 159 185 192 197 222

runflags: 24.92
spans: 3.95
indices: 2.99


runflags 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
span 0 1 10 11 20 21
indices 0 10 20

runflags: 3.84
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1
span 0 1 10 12 19 20 25 26
indices 0 10 11 19 25

runflags: 5.47
spans: 1.83
indices: 1.53


runflags 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 10 12 15 17 18 19 21 22 25 27 28 29 32 33 35 36 40 41 45 46 56 57
indices 0 10 11 15 16 18 21 25 26 28 32 35 40 45 56

runflags: 14.49
spans: 4.47
indices: 3.57


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
span 0 1 9 10 30 31 53 54 60 61 69 71 76 77 85 86 90 91 106 107 110 111 145 146 152 153 160 161 165 166 173 174 182 183 184 185 186 187 200 201 209 210
indices 0 9 30 53 60 69 70 76 85 90 106 110 145 152 160 165 173 182 184 186 200 209

runflags: 30.47
spans: 6.98
indices: 4.92


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1
span 0 1 9 10 29 30 39 40 52 53 56 57 62 63 64 65
indices 0 9 29 39 52 56 62 64

runflags: 9.84
spans: 2.90
indices: 2.13


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
span 0 1 9 10 23 25 46 48
indices 0 9 23 24 46 47

runflags: 6.98
spans: 1.99
indices: 1.72


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1
span 0 1 9 10 16 17 22 23
indices 0 9 16 22

runflags: 4.10
spans: 1.72
indices: 1.33


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1
span 0 1 9 10 14 15 16 17 19 21 29 30
indices 0 9 14 16 19 20 29

runflags: 6.14
spans: 2.39
indices: 1.94


runflags 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1
span 0 1 9 10 13 14 16 17 21 22 26 27 28 30 45 46 48 49 52 53 55 57 59 61 62 63 74 75 77 78 79 80 81 82 84 85
indices 0 9 13 16 21 26 28 29 45 48 52 55 56 59 60 62 74 77 79 81 84

runflags: 21.07
spans: 7.52
indices: 4.75


runflags 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
span 0 1 9 12 15 16 23 24 30 33 40 41 61 62 66 67 101 102 103 104
indices 0 9 10 11 15 23 30 31 32 40 61 66 101 103

runflags: 14.92
spans: 3.88
indices: 3.33


runflags 1 0 0 0 0 0 0 0 1
span 0 1 8 9
indices 0 8

runflags: 1.72
spans: 1.12
indices: 0.91


runflags 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 8 9 25 26 29 30 60 62 66 67 69 70 83 84 89 90 98 99 100 101 103 105 111 112 114 115 122 123 133 134 147 148 166 167 185 186 187 188 203 204
indices 0 8 25 29 60 61 66 69 83 89 98 100 103 104 111 114 122 133 147 166 185 187 203

runflags: 29.89
spans: 7.18
indices: 5.15


runflags 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
span 0 1 8 9 17 18
indices 0 8 17

runflags: 3.53
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1
span 0 1 8 9 14 15
indices 0 8 14

runflags: 3.09
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 0 1 0 0 0 0 1
span 0 1 8 9 13 14
indices 0 8 13

runflags: 3.02
spans: 1.41
indices: 1.17


runflags 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 8 9 11 12 41 42
indices 0 8 11 41

runflags: 5.39
spans: 1.72
indices: 1.34


runflags 1 0 0 0 0 0 0 1
span 0 1 7 8
indices 0 7

runflags: 1.68
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
span 0 1 7 8 17 18
indices 0 7 17

runflags: 2.64
spans: 1.41
indices: 1.16


runflags 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1
span 0 1 7 8 16 17 26 27
indices 0 7 16 26

runflags: 4.80
spans: 1.72
indices: 1.33


runflags 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 0 0 1
span 0 1 7 8 9 10 18 19 20 21 22 23 26 27 32 33 34 35 40 41 46 47 61 62 66 67 72 73 74 75 87 88 90 91 95 97 98 99 100 101 105 106 114 115 117 118 119 120 124 125 133 134 135 136 147 148 155 156 167 169 182 183 188 189 192 193 211 212 217 218 220 222 228 229 231 232
indices 0 7 9 18 20 22 26 32 34 40 46 61 66 72 74 87 90 95 96 98 100 105 114 117 119 124 133 135 147 155 167 168 182 188 192 211 217 220 221 228 231

runflags: 44.23
spans: 12.99
indices: 8.76


runflags 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1
span 0 1 7 8 9 10 17 18
indices 0 7 9 17

runflags: 2.80
spans: 1.72
indices: 1.33


runflags 1 0 0 0 0 0 1
span 0 1 6 7
indices 0 6

runflags: 1.51
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
span 0 1 6 7 41 42 44 45 49 50 54 55 60 61
indices 0 6 41 44 49 54 60

runflags: 8.23
spans: 2.61
indices: 1.94


runflags 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 6 7 24 25 44 45
indices 0 6 24 44

runflags: 6.17
spans: 1.72
indices: 1.33


runflags 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1
span 0 1 6 7 14 15 16 17 21 22 27 29 31 32 33 35 39 41 43 44 45 46 52 54 59 60 62 63 64 65 70 72 78 79
indices 0 6 14 16 21 27 28 31 33 34 39 40 43 45 52 53 59 62 64 70 71 78

runflags: 18.97
spans: 7.91
indices: 4.92


runflags 1 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1
span 0 1 6 7 11 12 14 15 18 19 23 24 28 29 31 32 35 36 40 41 49 50 51 52 53 54 60 62 64 66
indices 0 6 11 14 18 23 28 31 35 40 49 51 53 60 61 64 65

runflags: 14.65
spans: 5.94
indices: 3.95


runflags 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 6 7 9 10 13 14 16 17 20 21 33 34 48 49 55 56 73 74
indices 0 6 9 13 16 20 33 48 55 73

runflags: 11.83
spans: 3.37
indices: 2.54


runflags 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1
span 0 1 6 7 9 10 12 13 18 19 23 24 31 32 34 36 38 39 41 42 46 47 48 49 50 51 54 56 59 60 62 63 66 67 69 70 71 73 74 75 79 80 86 88 90 91 93 94 96 99 105 106 111 112 115 116 118 119 124 126 128 129 130 132 135 137 141 142 143 148 156 157 159 160 162 163 165 166 197 199 204 205 211 212 223 225 226 228 233 234 243 244 249 250 253 255
indices 0 6 9 12 18 23 31 34 35 38 41 46 48 50 54 55 59 62 66 69 71 72 74 79 86 87 90 93 96 97 98 105 111 115 118 124 125 128 130 131 135 136 141 143 144 145 146 147 156 159 162 165 197 198 204 211 223 224 226 227 233 243 249 253 254

runflags: 56.93
spans: 22.64
indices: 15.66


runflags 1 0 0 0 0 0 1 0 1
span 0 1 6 7 8 9
indices 0 6 8

runflags: 1.95
spans: 1.39
indices: 1.17


runflags 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 1 1 1 1
span 0 1 6 7 8 9 12 13 18 19 20 25
indices 0 6 8 12 18 20 21 22 23 24

runflags: 6.14
spans: 3.61
indices: 2.54


runflags 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1
span 0 1 6 8 9 10 15 16 18 19 24 25
indices 0 6 7 9 15 18 24

runflags: 5.83
spans: 2.42
indices: 1.94


runflags 1 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
span 0 1 6 8 9 10 11 12 13 15 16 17 38 39 43 45 46 47 49 50 58 59 60 61 67 68 70 72 77 78 83 85 87 88 91 92 107 108 116 117 124 125 127 129 131 133 135 137 145 146 148 150 154 155 157 158 159 163 174 175 178 180 182 183 184 186 195 197 200 201 208 209 216 217 218 219 227 228 229 230 237 238 243 244 245 246
indices 0 6 7 9 11 13 14 16 38 43 44 46 49 58 60 67 70 71 77 83 84 87 91 107 116 124 127 128 131 132 135 136 145 148 149 154 157 159 160 161 162 174 178 179 182 184 185 195 196 200 208 216 218 227 229 237 243 245

runflags: 52.67
spans: 20.64
indices: 12.09


runflags 1 0 0 0 0 1
span 0 1 5 6
indices 0 5

runflags: 1.64
spans: 1.11
indices: 0.91


runflags 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
span 0 1 5 6 22 23 30 31
indices 0 5 22 30

runflags: 4.45
spans: 1.72
indices: 1.33


runflags 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 5 6 17 18 19 21 22 23 61 62
indices 0 5 17 19 20 22 61

runflags: 8.03
spans: 2.45
indices: 1.94


runflags 1 0 0 0 0 1 0 0 0 0 0 0 1
span 0 1 5 6 12 13
indices 0 5 12

runflags: 2.65
spans: 1.39
indices: 1.16


runflags 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1
span 0 1 5 6 11 13 23 24 26 27 30 31 34 35 37 38 39 40
indices 0 5 11 12 23 26 30 34 37 39

runflags: 9.18
spans: 3.36
indices: 2.54


runflags 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 5 6 9 10 21 22 35 36 38 39 45 46 52 54 62 63 89 90 104 105
indices 0 5 9 21 35 38 45 52 53 62 89 104

runflags: 15.37
spans: 3.88
indices: 2.92


runflags 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
span 0 1 5 6 9 10 11 14 15 16 18 19 22 24 29 30 32 34 45 46 47 49 50 52 62 63 70 71 73 74 84 85 90 91 92 93
indices 0 5 9 11 12 13 15 18 22 23 29 32 33 45 47 48 50 51 62 70 73 84 90 92

runflags: 18.59
spans: 7.55
indices: 5.32


runflags 1 0 0 0 0 1 0 1 0 0 1
span 0 1 5 6 7 8 10 11
indices 0 5 7 10

runflags: 2.04
spans: 1.93
indices: 1.33


runflags 1 0 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1
span 0 1 5 7 9 12 13 14 17 19
indices 0 5 6 9 10 11 13 17 18

runflags: 3.40
spans: 2.55
indices: 2.37


runflags 1 0 0 0 0 1 1 1
span 0 1 5 8
indices 0 5 6 7

runflags: 2.07
spans: 1.41
indices: 1.33


runflags 1 0 0 0 1
span 0 1 4 5
indices 0 4

runflags: 0.99
spans: 1.14
indices: 0.96


runflags 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 4 5 23 24
indices 0 4 23

runflags: 3.87
spans: 1.41
indices: 1.16


runflags 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
span 0 1 4 5 13 14
indices 0 4 13

runflags: 3.20
spans: 1.41
indices: 1.16


runflags 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1
span 0 1 4 5 6 7 12 13 22 23 28 29 34 37
indices 0 4 6 12 22 28 34 35 36

runflags: 7.03
spans: 2.98
indices: 2.37


runflags 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1
span 0 1 4 5 6 9 18 19 22 23 31 32 35 36 45 47 54 55 56 57 60 61 63 64 66 67
indices 0 4 6 7 8 18 22 31 35 45 46 54 56 60 63 66

runflags: 14.18
spans: 5.37
indices: 3.71


runflags 1 0 0 0 1 1
span 0 1 4 6
indices 0 4 5

runflags: 1.09
spans: 1.25
indices: 1.16


runflags 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 1 1
span 0 1 4 6 7 8 11 12 15 16 17 20
indices 0 4 5 7 11 15 17 18 19

runflags: 3.94
spans: 2.72
indices: 2.36


runflags 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 1 1 0 1 1
span 0 1 4 25 26 29 30 35 36 37 38 40 41 43 44 47 48 50
indices 0 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 26 27 28 30 31 32 33 34 36 38 39 41 42 44 45 46 48 49

runflags: 9.64
spans: 11.57
indices: 8.48


runflags 1 0 0 1
span 0 1 3 4
indices 0 3

runflags: 0.88
spans: 1.11
indices: 0.91


runflags 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 0 1
span 0 1 3 4 13 16 17 18 20 22 26 28 30 32 33 34 36 37 40 41 48 49 51 52 54 55 56 57 60 63 67 68 74 75 78 79 81 82 83 84 86 88 90 91 95 96
indices 0 3 13 14 15 17 20 21 26 27 30 31 33 36 40 48 51 54 56 60 61 62 67 74 78 81 83 86 87 90 95

runflags: 25.70
spans: 10.95
indices: 8.67


runflags 1 0 0 1 0 0 0 0 0 1
span 0 1 3 4 9 10
indices 0 3 9

runflags: 2.20
spans: 1.41
indices: 1.16


runflags 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 1
span 0 1 3 4 8 9 14 17 23 24 26 28 29 30
indices 0 3 8 14 15 16 23 26 27 29

runflags: 6.89
spans: 2.94
indices: 2.54


runflags 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
span 0 1 3 4 7 8 17 18 25 26
indices 0 3 7 17 25

runflags: 3.98
spans: 1.99
indices: 1.53


runflags 1 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 1 0 1
span 0 1 3 4 7 10 11 13 16 17 19 20 21 22 33 34 36 37 38 39 42 43 44 46 47 48
indices 0 3 7 8 9 11 12 16 19 21 33 36 38 42 44 45 47

runflags: 11.19
spans: 5.52
indices: 3.95


runflags 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 1 1 0 0 0 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1
span 0 1 3 4 6 7 10 11 16 17 23 24 27 28 34 35 38 39 48 49 51 52 56 57 59 60 65 67 68 69 71 72 75 76 79 80 87 88 90 94 95 97 100 102 105 106 107 109 110 111 115 118 120 121 124 127 128 132 136 139 140 141 147 148 150 151 155 157 167 168 181 183 185 186 187 189 190 191 195 196 198 200 217 218 219 221 227 228 229 230 233 235 238 239 240 241 242 243 248 250
indices 0 3 6 10 16 23 27 34 38 48 51 56 59 65 66 68 71 75 79 87 90 91 92 93 95 96 100 101 105 107 108 110 115 116 117 120 124 125 126 128 129 130 131 136 137 138 140 147 150 155 156 167 181 182 185 187 188 190 195 198 199 217 219 220 227 229 233 234 238 240 242 248 249

runflags: 61.60
spans: 27.20
indices: 15.62


runflags 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1
span 0 1 3 4 6 8 13 14 15 16 19 20 21 24 25 26 28 30 37 40 43 44 50 51 52 53 54 58 61 63 73 74 78 79 84 85
indices 0 3 6 7 13 15 19 21 22 23 25 28 29 37 38 39 43 50 52 54 55 56 57 61 62 73 78 84

runflags: 19.25
spans: 10.91
indices: 6.10


runflags 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1
span 0 1 3 4 5 6 8 9 19 20 26 27 31 33 37 38 50 51 63 65 74 76 78 79 81 82 86 87 90 91 93 95 100 101 103 104 105 106 108 109 113 114 115 116
indices 0 3 5 8 19 26 31 32 37 50 63 64 74 75 78 81 86 90 93 94 100 103 105 108 113 115

runflags: 23.11
spans: 8.79
indices: 5.71


runflags 1 0 0 1 1
span 0 1 3 5
indices 0 3 4

runflags: 1.23
spans: 1.33
indices: 1.24


runflags 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1
span 0 1 3 5 30 33 37 38 39 40 47 48 49 50
indices 0 3 4 30 31 32 37 39 47 49

runflags: 7.25
spans: 3.09
indices: 2.54


runflags 1 0 0 1 1 0 0 0 0 0 0 0 1
span 0 1 3 5 12 13
indices 0 3 4 12

runflags: 2.61
spans: 1.55
indices: 1.33


runflags 1 0 0 1 1 0 0 1 0 0 0 0 0 0 1
span 0 1 3 5 7 8 14 15
indices 0 3 4 7 14

runflags: 2.80
spans: 1.83
indices: 1.53


runflags 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1
span 0 1 3 7 18 22 33 34 35 37 38 40 47 48 56 58 59 60 63 64 65 68
indices 0 3 4 5 6 18 19 20 21 33 35 36 38 39 47 56 57 59 63 65 66 67

runflags: 13.85
spans: 7.93
indices: 4.93


runflags 1 0 1
span 0 1 2 3
indices 0 2

runflags: 0.86
spans: 1.11
indices: 0.91


runflags 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
span 0 1 2 3 35 36 42 43
indices 0 2 35 42

runflags: 5.01
spans: 1.72
indices: 1.33


runflags 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 2 3 20 21
indices 0 2 20

runflags: 3.00
spans: 1.41
indices: 1.16


runflags 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 2 3 16 17
indices 0 2 16

runflags: 2.65
spans: 1.41
indices: 1.16


runflags 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 1
span 0 1 2 3 10 12 16 17 18 19 21 22
indices 0 2 10 11 16 18 21

runflags: 4.86
spans: 2.31
indices: 1.95


runflags 1 0 1 0 0 0 0 1
span 0 1 2 3 7 8
indices 0 2 7

runflags: 2.02
spans: 1.40
indices: 1.16


runflags 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 2 3 6 7 14 15 16 18 20 21 25 26 32 33 38 39 41 42 43 44 52 53 66 67
indices 0 2 6 14 16 17 20 25 32 38 41 43 52 66

runflags: 12.69
spans: 4.61
indices: 3.33


runflags 1 0 1 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 1 0 1
span 0 1 2 3 5 7 9 12 15 16 18 21 22 24 25 27 28 29 31 36 41 42 43 46 47 48 49 50 51 53 54 57 60 61 64 65 67 68 71 72 73 74 75 79 85 87 89 92 96 98 99 100 103 104 106 107 112 116 117 118
indices 0 2 5 6 9 10 11 15 18 19 20 22 23 25 26 28 31 32 33 34 35 41 43 44 45 47 49 51 52 54 55 56 60 64 67 71 73 75 76 77 78 85 86 89 90 91 96 97 99 103 106 112 113 114 115 117

runflags: 36.97
spans: 23.11
indices: 11.66


runflags 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
span 0 1 2 3 4 5 12 13 23 24
indices 0 2 4 12 23

runflags: 3.92
spans: 1.99
indices: 1.53


runflags 1 0 1 0 1 0 0 0 0 0 1 0 1 1
span 0 1 2 3 4 5 10 11 12 14
indices 0 2 4 10 12 13

runflags: 3.49
spans: 2.18
indices: 1.72


runflags 1 0 1 0 1 0 0 1
span 0 1 2 3 4 5 7 8
indices 0 2 4 7

runflags: 1.30
spans: 1.71
indices: 1.36


runflags 1 0 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1
span 0 1 2 3 4 5 6 7 12 14 15 16 19 20 21 22 23 24 25 26 27 28 29 33 34 35 38 40 46 51 56 58
indices 0 2 4 6 12 13 15 19 21 23 25 27 29 30 31 32 34 38 39 46 47 48 49 50 56 57

runflags: 13.40
spans: 9.68
indices: 5.71


runflags 1 0 1 0 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 0 0 0 1 1 1 1 0 1 1 0 1 1 1 0 1
span 0 1 2 3 4 11 13 15 16 17 18 19 22 26 27 29 30 33 34 35
indices 0 2 4 5 6 7 8 9 10 13 14 16 18 22 23 24 25 27 28 30 31 32 34

runflags: 10.08
spans: 8.26
indices: 5.15


runflags 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1
span 0 1 2 4 11 12 17 19 21 22 24 25 38 40 43 44 47 49 53 54 56 57 63 64 70 71
indices 0 2 3 11 17 18 21 24 38 39 43 47 48 53 56 63 70

runflags: 15.08
spans: 5.96
indices: 3.95


runflags 1 0 1 1 0 0 0 0 0 0 1
span 0 1 2 4 10 11
indices 0 2 3 10

runflags: 2.46
spans: 1.55
indices: 1.34


runflags 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 0 1 0 1 1
span 0 1 2 4 6 10 11 12 13 25 27 28 29 33 35 37 39 40 41 43
indices 0 2 3 6 7 8 9 11 13 14 15 16 17 18 19 20 21 22 23 24 27 29 30 31 32 35 36 39 41 42

runflags: 9.45
spans: 9.20
indices: 6.51


runflags 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
span 0 1 2 5 8 9 17 18 23 24
indices 0 2 3 4 8 17 23

runflags: 4.39
spans: 2.27
indices: 1.94


runflags 1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 1
span 0 1 2 6 13 16 18 19 22 23
indices 0 2 3 4 5 13 14 15 18 22

runflags: 5.16
spans: 3.02
indices: 2.54


runflags 1 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1
span 0 1 2 6 10 11 13 16 23 24 27 29 32 33 37 39 40 43 46 48 52 54 62 65 66 67 68 69 72 73 74 77 78 79 80 81
indices 0 2 3 4 5 10 13 14 15 23 27 28 32 37 38 40 41 42 46 47 52 53 62 63 64 66 68 72 74 75 76 78 80

runflags: 20.25
spans: 13.32
indices: 7.15


runflags 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1
span 0 1 2 20 21 29 31 40
indices 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 31 32 33 34 35 36 37 38 39

runflags: 8.00
spans: 7.22
indices: 7.70


runflags 1 1
span 0 2
indices 0 1

runflags: 0.83
spans: 1.02
indices: 0.91


runflags 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 2 22 23 58 59
indices 0 1 22 58

runflags: 6.50
spans: 1.51
indices: 1.33


runflags 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 2 17 18
indices 0 1 17

runflags: 2.34
spans: 1.21
indices: 1.16


runflags 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1
span 0 2 10 11 12 13 19 20 21 22 23 24 31 32
indices 0 1 10 12 19 21 23 31

runflags: 5.23
spans: 2.78
indices: 2.12


runflags 1 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1
span 0 2 8 9 10 11 14 15 17 18
indices 0 1 8 10 14 17

runflags: 4.53
spans: 2.17
indices: 1.72


runflags 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 1
span 0 2 7 8 16 17 25 26 33 34 35 36 38 40 44 45 49 51 53 54
indices 0 1 7 16 25 33 35 38 39 44 49 50 53

runflags: 10.02
spans: 4.16
indices: 3.16


runflags 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1
span 0 2 7 8 16 18 20 22
indices 0 1 7 16 17 20 21

runflags: 4.35
spans: 2.05
indices: 1.94


runflags 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1
span 0 2 7 8 13 15 18 19 20 21 33 34 35 37 50 51 57 58 65 66 67 68
indices 0 1 7 13 14 18 20 33 35 36 50 57 65 67

runflags: 13.99
spans: 4.31
indices: 3.33


runflags 1 1 0 0 0 1
span 0 2 5 6
indices 0 1 5

runflags: 1.12
spans: 1.28
indices: 1.16


runflags 1 1 0 0 0 1 1 0 0 1 1 1 0 0 0 1
span 0 2 5 7 9 12 15 16
indices 0 1 5 6 9 10 11 15

runflags: 3.85
spans: 2.20
indices: 2.13


runflags 1 1 0 0 1
span 0 2 4 5
indices 0 1 4

runflags: 1.07
spans: 1.30
indices: 1.16


runflags 1 1 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1
span 0 2 4 5 11 13 15 17 23 24 27 29 40 42 48 49 51 52 58 59 63 65 68 69 73 74 76 77 81 82 83 84 88 89 91 92 96 97 98 100 103 104 105 107 109 110 113 114 115 117 124 125 126 127 130 131 139 140 151 152 153 154 156 157 160 161 165 167 168 169 177 178 184 185 188 189 190 192 194 195 197 198 202 203 206 207 208 209 210 212 214 215 227 228 229 230 239 240 241 242
indices 0 1 4 11 12 15 16 23 27 28 40 41 48 51 58 63 64 68 73 76 81 83 88 91 96 98 99 103 105 106 109 113 115 116 124 126 130 139 151 153 156 160 165 166 168 177 184 188 190 191 194 197 202 206 208 210 211 214 227 229 239 241

runflags: 61.15
spans: 19.92
indices: 12.87


runflags 1 1 0 0 1 0 0 0 0 1
span 0 2 4 5 9 10
indices 0 1 4 9

runflags: 2.36
spans: 1.57
indices: 1.36


runflags 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
span 0 2 4 5 9 10 16 17 21 22 27 28 39 40
indices 0 1 4 9 16 21 27 39

runflags: 6.60
spans: 2.77
indices: 2.12


runflags 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1
span 0 2 4 5 7 9 14 15 18 19
indices 0 1 4 7 8 14 18

runflags: 4.43
spans: 2.22
indices: 1.94


runflags 1 1 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1
span 0 2 4 6 7 10 12 13 19 20 22 23 25 26 28 33 42 43 45 46 49 51 53 54 60 61 62 63 65 66 69 70 74 75 76 77 79 80 84 87 89 90 92 93 99 100 107 109 111 112 113 115 118 120 124 126 140 141 143 144 146 149 156 158 159 160 166 167 170 172 174 175 177 179 182 184 193 194 195 196 197 198 199 203 207 208 209 210 212 213 216 217 222 223 227 228 232 233 236 237 238 239 244 245 246 247
indices 0 1 4 5 7 8 9 12 19 22 25 28 29 30 31 32 42 45 49 50 53 60 62 65 69 74 76 79 84 85 86 89 92 99 107 108 111 113 114 118 119 124 125 140 143 146 147 148 156 157 159 166 170 171 174 177 178 182 183 193 195 197 199 200 201 202 207 209 212 216 222 227 232 236 238 244 246

runflags: 62.54
spans: 28.38
indices: 16.79


runflags 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 2 3 4 10 11 12 13 26 27
indices 0 1 3 10 12 26

runflags: 4.18
spans: 2.34
indices: 1.97


runflags 1 1 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1
span 0 2 3 4 9 10 12 17 18 19 21 22 24 28 29 31
indices 0 1 3 9 12 13 14 15 16 18 21 24 25 26 27 29 30

runflags: 7.10
spans: 6.11
indices: 4.05


runflags 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1
span 0 2 3 4 5 7 8 9 10 11 12 13 17 19 21 23 24 27 32 35 38 39 40 42
indices 0 1 3 5 6 8 10 12 17 18 21 22 24 25 26 32 33 34 38 40 41

runflags: 10.92
spans: 8.26
indices: 4.75


runflags 1 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
span 0 2 3 4 5 14 15 21 22 23 24 37 38 43
indices 0 1 3 5 6 7 8 9 10 11 12 13 15 16 17 18 19 20 22 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 42

runflags: 8.67
spans: 9.14
indices: 7.95


runflags 1 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 1 1 0 1 0 0 1 1
span 0 2 3 8 10 15 16 22 23 29 30 32 33 35 36 38 39 41 42 43 44 45 46 47 48 56 57 60 61 66 67 71 72 74 75 77 78 80 82 83 86 87 88 90 91 95 96 97 99 101
indices 0 1 3 4 5 6 7 10 11 12 13 14 16 17 18 19 20 21 23 24 25 26 27 28 30 31 33 34 36 37 39 40 42 44 46 48 49 50 51 52 53 54 55 57 58 59 61 62 63 64 65 67 68 69 70 72 73 75 76 78 79 82 86 88 89 91 92 93 94 96 99 100

runflags: 27.60
spans: 23.17
indices: 15.16


runflags 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 1 1 1 0 0 1 1
span 0 2 3 8 9 10 15 16 19 20 22 23 26 29 30 31 32 33 38 39 40 44 46 48
indices 0 1 3 4 5 6 7 9 15 19 22 26 27 28 30 32 38 40 41 42 43 46 47

runflags: 12.19
spans: 8.17
indices: 5.14


runflags 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 2 3 9 15 16 20 21 22 23 33 35 48 50 51 52 62 65 66 67 69 71 78 79 80 82 83 84 99 100 113 114 116 118 126 127 129 131 132 133 145 146 174 178 192 193 194 195 207 208 222 223 224 225 239 240
indices 0 1 3 4 5 6 7 8 15 20 22 33 34 48 49 51 62 63 64 66 69 70 78 80 81 83 99 113 116 117 126 129 130 132 145 174 175 176 177 192 194 207 222 224 239

runflags: 38.54
spans: 17.05
indices: 9.55


runflags 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 2 3 23 24 42 43 61
indices 0 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

runflags: 10.07
spans: 9.22
indices: 12.09


runflags 1 1 1
span 0 3
indices 0 1 2

runflags: 1.02
spans: 1.14
indices: 1.20


runflags 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1
span 0 3 6 7 8 9 15 16 19 22 24 25
indices 0 1 2 6 8 15 19 20 21 24

runflags: 6.06
spans: 2.76
indices: 2.54


runflags 1 1 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1
span 0 3 6 7 8 9 10 11 12 13 17 20 26 30 33 35 36 37 41 42 43 44 47 48 49 52
indices 0 1 2 6 8 10 12 17 18 19 26 27 28 29 33 34 36 41 43 47 49 50 51

runflags: 14.05
spans: 8.76
indices: 5.14


runflags 1 1 1 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 1
span 0 3 5 6 7 8 11 12 15 16 20 22 26 28 30 31 33 36 39 43
indices 0 1 2 5 7 11 15 20 21 26 27 30 33 34 35 39 40 41 42

runflags: 11.37
spans: 6.69
indices: 4.54


runflags 1 1 1 0 1
span 0 3 4 5
indices 0 1 2 4

runflags: 1.28
spans: 1.44
indices: 1.54


runflags 1 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 1
span 0 3 4 5 6 8 9 10 11 12 14 17 19 20 22 24 29 31 39 42 43 46 59 60 61 62 63 64 66 68 73 74 75 78
indices 0 1 2 4 6 7 9 11 14 15 16 19 22 23 29 30 39 40 41 43 44 45 59 61 63 66 67 73 75 76 77

runflags: 17.69
spans: 13.26
indices: 6.78


runflags 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 1
span 0 3 4 11 12 14 15 37 38 42 43 52 53 68 72 77 78 81
indices 0 1 2 4 5 6 7 8 9 10 12 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 43 44 45 46 47 48 49 50 51 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 72 73 74 75 76 78 79 80

runflags: 16.87
spans: 14.48
indices: 14.78


runflags 1 1 1 1 1 1 1 1
span 0 8
indices 0 1 2 3 4 5 6 7

runflags: 1.69
spans: 1.72
indices: 2.13


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 16
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

runflags: 2.86
spans: 2.73
indices: 3.72


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1
span 0 16 17 22 23 27 29 32 33 34 36 41
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 18 19 20 21 23 24 25 26 29 30 31 33 36 37 38 39 40

runflags: 8.90
spans: 8.39
indices: 7.31


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 23
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

runflags: 3.89
spans: 3.61
indices: 5.14


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 30
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

runflags: 4.92
spans: 4.50
indices: 6.52


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 31
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

runflags: 5.05
spans: 4.61
indices: 6.74


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 48
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

runflags: 7.54
spans: 7.14
indices: 10.08


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 80
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

runflags: 12.61
spans: 11.14
indices: 16.75


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 102
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

runflags: 15.89
spans: 13.90
indices: 21.14




--
Larry Gritz
l...@...


Larry Gritz <l...@...>
 

OK, so what do we make of all this? I've quoted a few interesting cases below.


Most of the unique state patterns look like this, typical sparse runflags from secondary ray batches: runflags are awful, they spend too much time on points that are "off" (and the bigger the batches are, the more runflags suck). Either spans or indices are a HUGE speedup (2-8x, depending on batch size), with indices being about 20% faster than spans.

runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 93 95 102 103 146 147 191 192
indices 0 93 94 102 146 191

runflags: 18.31
spans: 2.15
indices: 1.72


runflags 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
span 0 1 64 65
indices 0 64

runflags: 5.21
spans: 1.10
indices: 0.91


runflags 1 0 0 0 0 0 0 0 0 0 1
span 0 1 10 11
indices 0 10

runflags: 1.76
spans: 1.11
indices: 0.91

But when npoints is sufficiently small, runflags wins (though indices are VERY close in speed):


runflags 1 0 0 1
span 0 1 3 4
indices 0 3

runflags: 0.88
spans: 1.11
indices: 0.91

runflags 1 0 1
span 0 1 2 3
indices 0 2

runflags: 0.86
spans: 1.11
indices: 0.91

The very common case of a single point on:

runflags 1
span 0 1
indices 0

runflags: 0.68
spans: 0.84
indices: 0.75

In typical inside-conditional states or fairly coherent secondaries, indices are the clear winner, even beating spans handily:

runflags 1 0 1 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 1 0 1
span 0 1 2 3 5 7 9 12 15 16 18 21 22 24 25 27 28 29 31 36 41 42 43 46 47 48 49 50 51 53 54 57 60 61 64 65 67 68 71 72 73 74 75 79 85 87 89 92 96 98 99 100 103 104 106 107 112 116 117 118
indices 0 2 5 6 9 10 11 15 18 19 20 22 23 25 26 28 31 32 33 34 35 41 43 44 45 47 49 51 52 54 55 56 60 64 67 71 73 75 76 77 78 85 86 89 90 91 96 97 99 103 106 112 113 114 115 117

runflags: 36.97
spans: 23.11
indices: 11.66


runflags 1 0 1 1 1 1 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1
span 0 1 2 6 10 11 13 16 23 24 27 29 32 33 37 39 40 43 46 48 52 54 62 65 66 67 68 69 72 73 74 77 78 79 80 81
indices 0 2 3 4 5 10 13 14 15 23 27 28 32 37 38 40 41 42 46 47 52 53 62 63 64 66 68 72 74 75 76 78 80

runflags: 20.25
spans: 13.32
indices: 7.15

But for long spans of 1's, which are very rare for secondaries but dominate primary batches, spans are the fastest and indices the slowest:


runflags 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 2 3 23 24 42 43 61
indices 0 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

runflags: 10.07
spans: 9.22
indices: 12.09


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 16
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

runflags: 2.86
spans: 2.73
indices: 3.72


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1
span 0 16 17 22 23 27 29 32 33 34 36 41
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 18 19 20 21 23 24 25 26 29 30 31 33 36 37 38 39 40

runflags: 8.90
spans: 8.39
indices: 7.31




runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 48
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

runflags: 7.54
spans: 7.14
indices: 10.08


runflags 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
span 0 102
indices 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

runflags: 15.89
spans: 13.90
indices: 21.14
--
Larry Gritz
l...@...


Larry Gritz <l...@...>
 

On Feb 4, 2010, at 11:32 AM, Christopher Kulla wrote:

My interpretation of these results is that indices always win - unless
we have a single span.
Spans only beat indices if there are is a single large span of 1's, or a large batch that is almost all 1's. (That's most primary batches, but nothing else.)


It might be worth using indices but having an
"all_points_sequential" optimization for simple ops where the
indirection overhead would be noticeable (all the templated ops can
get this for free)
That may be a good compromise. I think indices are a clear winner in all other cases, so perhaps this will eliminate the overhead in the few cases that spans seem to win, and then we're golden.


By the way - I don't really understand how you got any runflag
sequences that started with 0. Did you always dump out "npoints" or
only "begin/end" ?
I dumped out "npoints" but for the index test, only loop on [begin,end), as we do in the real shadeops. So there is no penalty for strings of 0's on either end. So primary batches (or conditional modifications to primary batches) can start with 0. Non-conditional secondary batches always start with 1 (because of the way our renderer sends them to OSL).


--
Larry Gritz
l...@...


Larry Gritz <l...@...>
 

The most important data point is that runflags are a big loser for the vast majority of run states that we see. So moving to one of the others (almost certainly indices) is at the top of my plate.

By the way, when we first opened OSL a few weeks back, we noted that we were working hard on optimization, still being 5-10x slower than our old C shaders. We've been working with a target production frame that was a bit of a worst-case scenario, which was slightly more that 15x slower than the equivalent frame with our old C shaders as of 3 weeks ago. At the beginning of this week, we had closed the gap on this scene to 3.5x (not counting changes from this week). Which we think means that less worst-case scenarios are probably getting very close to parity, and we are still working on more optimization, as you can see from this thread.

Some of that speedup was due to changes on the OSL side (all of which you have seen played out in reviews and checkins), but the lion's share was due to changing the renderer to batch the shading requests, including secondary rays. There are two big takeaways for you, dear readers:

1. Tales of OSL's inherent slowness where highly exaggerated. All along, most of the performance problem was due to our renderer's habit of shading one point at a time (despite liboslexec's being designed around batches). When we finally batched the points (especially secondary rays, even when we could only batch a few), and rewrote our integrator to be batch-oriented, we squeezed out a factor of 5 quite easily.

2. For those of you integrating OSL into other renderers, please learn from our mistake and use batches from the start!

-- lg


On Feb 4, 2010, at 11:42 AM, Larry Gritz wrote:

On Feb 4, 2010, at 11:32 AM, Christopher Kulla wrote:

My interpretation of these results is that indices always win - unless
we have a single span.
Spans only beat indices if there are is a single large span of 1's, or a large batch that is almost all 1's. (That's most primary batches, but nothing else.)


It might be worth using indices but having an
"all_points_sequential" optimization for simple ops where the
indirection overhead would be noticeable (all the templated ops can
get this for free)
That may be a good compromise. I think indices are a clear winner in all other cases, so perhaps this will eliminate the overhead in the few cases that spans seem to win, and then we're golden.


By the way - I don't really understand how you got any runflag
sequences that started with 0. Did you always dump out "npoints" or
only "begin/end" ?
I dumped out "npoints" but for the index test, only loop on [begin,end), as we do in the real shadeops. So there is no penalty for strings of 0's on either end. So primary batches (or conditional modifications to primary batches) can start with 0. Non-conditional secondary batches always start with 1 (because of the way our renderer sends them to OSL).
--
Larry Gritz
l...@...


Chris Foster <chri...@...>
 

Hi guys,

Nice job with the analysis Larry. It's interesting to see the kinds of
runstates which come out of your renderer, especially the apparent
predominance of really sparse states (at a quick eyeball). Based on the
spareseness, my analysis from a week ago would suggest that the indices are
going to win handily, and your data definitely confirms that!


To find out exactly what the average sparseness is, here's a script.

--------------------------------------------------
#!/usr/bin/python

from __future__ import division

f = open('rf.txt')

fractionOn = 0
totStates = 0

for line in f.readlines():
line = line.split()
count = int(line[0])
rf = [int(f) for f in line[2:]]
nFlags = len(rf)
nOn = len(filter(lambda x: x == 1, rf))
fractionOn += count * nOn/nFlags
totStates += count

fractionOn /= totStates

print fractionOn
--------------------------------------------------

The output for your data - excluding the 4285 non-batched points for which the
indices win anyway - is an average fraction of 0.31 states turned on which
matches with the impression you get from looking at the states by eye.


Almost the only cases where the spans method wins definitively are the all-on
case, so I agree that a special case optimization is in order. I found the
timings for the following mostly-on state particularly interesting:

runflags 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 1
span 0 3 4 11 12 14 15 37 38 42 43 52 53 68 72 77 78 81
indices 0 1 2 4 5 6 7 8 9 10 12 13 15 16 17 18 19 20 21 22 23 24 25
26 27 28 29 30 31 32 33 34 35 36 38 39 40 41 43 44 45 46 47 48 49 50
51 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 72 73 74 75 76 78 79
80

runflags: 16.87
spans: 14.48
indices: 14.78

My intuition _was_ that the spans method would win quite comfortably here (given
that it appears to win handily in the all-on case), but no, it doesn't!


Regarding implementation, it would be nice to find a way to specify the
iteration strategy in a single place in the codebase. In the absence of
non-clumsy closure support in the C++, maybe a macro is in order?

#define RUNSTATE_LOOP(runstate, currIdx, loopBody) \
if(runstate.nactive == runstate.npoints) {
/* optimization for all active points */
for(int currIdx = 0; currIdx < runstate.nactive; ++currIdx) {
loopBody
}
}
else {
for(int j = 0; j < runstate.nactive; ++j) {
int currIdx = runstate.active[j];
loopBody
}
}


This would replace current stuff like

for (int i = beginpoint; i < endpoint; ++i)
if (runflags[i])
function (result[i], a[i], b[i], c[i], d[i]);

with

RUNSTATE_LOOP(runstate, i,
function (result[i], a[i], b[i], c[i], d[i]);
)


Ok, I don't like having to use a macro, but IMHO this is probably more
maintainable than the alternatives. Is it general enough?

Note that I've assumed that your runstates are passed around as a
self-contained but lightweight struct rather than the (runflags, beginactive,
endactive) triple currently used.


~Chris.


Larry Gritz <l...@...>
 

On Feb 4, 2010, at 11:57 AM, Larry Gritz wrote:
The most important data point is that runflags are a big loser for the vast majority of run states that we see. So moving to one of the others (almost certainly indices) is at the top of my plate.
Now I've spent nearly a week doing the comprehensive changes that allows a compile-time switch to select whether we use runflags, explicit indices, or spans. (Most of that time fixing the subtle bugs in what amounted to a wholesale reimplementation, twice over, of the 3-4 trickiest shadeops.)

The results are highly disappointing. As an example, on our favorite production benchmark,

3:27 use just runflags
3:29 use just indices
3:26 use just spans

The difference between these is within the measurement error -- the tests can vary a second or two from run to run. It's also identical to the timing before I made any of these changes.

I'm perplexed and disappointed. In our test harness, it seemed like runflags were a big loser, and that probably indices were the best overall. We were typically seeing an "add"-like loop go 30%-10x faster (depending on the runflag characteristics), so I'd hoped for a sizeable speedup in render time, maybe 20%.

I have two hypotheses to explain these results:

1. None of runflags/indices/spans won ALL the scenarios, perhaps in the real world we have just the right mixture of one-point (runflags win), nearly-all-on (spans win), and sparse (indices win) that all strategies do the same overall.

2. Perhaps in the context of the real scene in the real renderer, performance is bottlenecked on something completely different than in the test program. Maybe we are so memory-bandwidth limited that the slightly tighter loops and not having to branch with the runflag check just doesn't make any difference one way or the other.

3. Perhaps "add" is not typical after all, and the shadeops that really take most of the time have different characteristics and were not affected much by which runstate strategy we used.

Does anybody else have any good ideas?

I will put the code on the codereview tool so you can see it. The changes make a just a couple spots ugly with #ifdef's, the majority of the shadeops are no less readable than before (with my macros). So I'm tempted to commit it, because I have a feeling that there are other changes we may make to the system after which we may wish to revisit the runflag/indices/spans issue. Perhaps the balance will shift and there is utility in retaining the compile-time ability to switch strategies.

-- lg

--
Larry Gritz
l...@...


Chris Foster <chri...@...>
 

On Mon, Feb 15, 2010 at 6:09 AM, Larry Gritz <l...@...> wrote:
The results are highly disappointing.  As an example, on our favorite
production benchmark,

    3:27   use just runflags
    3:29   use just indices
    3:26   use just spans
Oh gosh, this is very surprising and disappointing.

I do know that when I tried a partial implementation of this idea with aqsis'
shader virtual machine ages ago I was getting speedups of 15% or so for some
shaders, and that was without removing the aqsis runflags stuff entirely. The
renderman shader I remember having good speedup in testing was a volume
integrator so it was a pretty heavy shader load with plenty of simple
shadeops. It was also probably very coherent.

I have two hypotheses to explain these results:

1. None of runflags/indices/spans won ALL the scenarios, perhaps in the real
world we have just the right mixture of one-point (runflags win),
nearly-all-on (spans win), and sparse (indices win) that all strategies do
the same overall.
Sounds like too much of a coincidence to me. Also, if you're using
all-points-on detection shouldn't the single point on for indices & spans be
just as fast as the runflags method?

2. Perhaps in the context of the real scene in the real renderer,
performance is bottlenecked on something completely different than in the
test program.  Maybe we are so memory-bandwidth limited that the slightly
tighter loops and not having to branch with the runflag check just doesn't
make any difference one way or the other.
This could be the case; some cache profiling would give a better idea if this
is plausible or not. I've found that profiling the cache using valgrind's
callgrind tool has been invaluable in the past.

3. Perhaps "add" is not typical after all, and the shadeops that really take
most of the time have different characteristics and were not affected much
by which runstate strategy we used.
Could be :-(

Does anybody else have any good ideas?
How about some synthetic benchmarks of OSL outside the context of the
renderer? Ok, so it wouldn't be a production example, but it might give some
idea of whether this is _ever_ going to be useful or whether it's an entirely
lost cause. Playing with various synthetic example shaders will probably give
some insight into why this didn't work and in what circumstances the changes
could be useful.

I will put the code on the codereview tool so you can see it.  The changes
make a just a couple spots ugly with #ifdef's, the majority of the shadeops
are no less readable than before (with my macros).  So I'm tempted to
commit it, because I have a feeling that there are other changes we may make
to the system after which we may wish to revisit the runflag/indices/spans
issue.  Perhaps the balance will shift and there is utility in retaining
the compile-time ability to switch strategies.
Sure, I'd be interested to see the code.

~Chris