Difference between revisions of "User:Becky Pippen"

From Second Life Wiki
Jump to navigation Jump to search
m
m
Line 37: Line 37:


== LSL Timings and Rates ==
== LSL Timings and Rates ==
Here are some LSL function times and event rates. There are three times reported for each: ''1.'' LSL scripts compiled by the client-based LSL compiler on non-Mono regions executed by non-Mono VM back end, ''2.'' LSL compiled by the sim-based LSL compiler on a Mono region and executed by the old LSL back end in a Mono region, and ''3.'' LSL compiled by the Mono compiler and executed by the Mono back end.
Here are some LSL function times and event rates comparing scripts compiled and run using the old LSL toolset and using Mono.


The basic test framework for these tests is to set i to a large value, and take the difference in llGetTime() before and after this loop (the loop is partially unrolled to make the loop control structure overhead negligible), and take several measurements in multiple sims (with sim total frame times < 10 ms) until the numbers converge with a variation of 10% or less:
The basic test framework for these tests is to set i to a large value, and take the difference in llGetTime() before and after this loop (the loop is partially unrolled to make the loop control structure overhead negligible), and take several measurements in multiple sims (with sim total frame times < 10 ms) until the numbers converge with a variation of 10% or less:
Line 54: Line 54:
|-
|-
|align="center" width="300" rowspan="2"|call to empty f() { }
|align="center" width="300" rowspan="2"|call to empty f() { }
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.33
|align="center"|0.33
|align="center"|0.88
|align="center"|0.0026
|align="center"|0.0026
|align="center"|ms/call  
|align="center"|ms/call  
Line 69: Line 67:
|-
|-
|align="center" width="300" rowspan="2"|v = <PI,PI,PI> + <PI,PI,PI> * PI;
|align="center" width="300" rowspan="2"|v = <PI,PI,PI> + <PI,PI,PI> * PI;
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.43
|align="center"|0.43
|align="center"|1.1
|align="center"|0.022
|align="center"|0.022
|align="center"|ms/statement  
|align="center"|ms/statement  
Line 85: Line 81:
|align="center" width="300" rowspan="2"|call to llCSV2List(llList2CSV(x));
|align="center" width="300" rowspan="2"|call to llCSV2List(llList2CSV(x));
where x is a list of 10 integers
where x is a list of 10 integers
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|3.2
|align="center"|3.2
|align="center"|8.1
|align="center"|4.0
|align="center"|4.0
|align="center"|ms/call  
|align="center"|ms/call  
Line 100: Line 94:
|-
|-
|align="center" width="300" rowspan="2"|call to llGetInventoryName(INVENTORY_TEXTURE, 0);
|align="center" width="300" rowspan="2"|call to llGetInventoryName(INVENTORY_TEXTURE, 0);
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.52
|align="center"|0.52
|align="center"|1.4
|align="center"|0.16
|align="center"|0.16
|align="center"|ms/call  
|align="center"|ms/call  
Line 115: Line 107:
|-
|-
|align="center" width="300" rowspan="2"|call to llGetPos();
|align="center" width="300" rowspan="2"|call to llGetPos();
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.44
|align="center"|0.44
|align="center"|1.05
|align="center"|0.047
|align="center"|0.047
|align="center"|ms/call  
|align="center"|ms/call  
Line 131: Line 121:
|align="center" width="300" rowspan="2"|call to llList2Vector(x, 0);
|align="center" width="300" rowspan="2"|call to llList2Vector(x, 0);
where x = [ ZERO_VECTOR ]
where x = [ ZERO_VECTOR ]
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.55
|align="center"|0.55
|align="center"|1.5
|align="center"|0.013
|align="center"|0.013
|align="center"|ms/call  
|align="center"|ms/call  
Line 147: Line 135:
|align="center" width="300" rowspan="2"|call to llMD5String(s,0);
|align="center" width="300" rowspan="2"|call to llMD5String(s,0);
where s is a 64-char string
where s is a 64-char string
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|1.4
|align="center"|1.4
|align="center"|2.7
|align="center"|1.4
|align="center"|1.4
|align="center"|ms/call  
|align="center"|ms/call  
Line 163: Line 149:
|align="center" width="300" rowspan="2"|call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);
|align="center" width="300" rowspan="2"|call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);
One consumer script with empty link_message() { }
One consumer script with empty link_message() { }
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|1.0
|align="center"|1.0
|align="center"|2.9
|align="center"|0.90
|align="center"|0.90
|align="center"|ms/call  
|align="center"|ms/call  
Line 180: Line 164:
|align="center" width="300" rowspan="2"|call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);
|align="center" width="300" rowspan="2"|call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);
32 - 64 consumer scripts with empty link_message() { }
32 - 64 consumer scripts with empty link_message() { }
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|11 or 22.2
|align="center"|11 or 22.2
|align="center"|11 or 22.2
|align="center"|11 or 22.2
|align="center"|11 or 22.2
Line 195: Line 177:
|-
|-
|align="center" width="300" rowspan="2"|call to llSay(-2, "0123456789");
|align="center" width="300" rowspan="2"|call to llSay(-2, "0123456789");
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|0.9
|align="center"|0.9
|align="center"|2.2
|align="center"|0.6
|align="center"|0.6
|align="center"|ms/call  
|align="center"|ms/call  
Line 210: Line 190:
|-
|-
|align="center" width="300" rowspan="2"|call to llSubStringIndex(s, "X"); where s is 10000 digits not containing "X"
|align="center" width="300" rowspan="2"|call to llSubStringIndex(s, "X"); where s is 10000 digits not containing "X"
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|16
|align="center"|16
|align="center"|23
|align="center"|22
|align="center"|22
|align="center"|ms/call  
|align="center"|ms/call  
Line 227: Line 205:
|-
|-
|align="center" width="300" rowspan="2"|Maximum rate of dataserver() events after llGetNotecardLine()
|align="center" width="300" rowspan="2"|Maximum rate of dataserver() events after llGetNotecardLine()
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|6.4
|align="center"|6.4
|align="center"|6.4
|align="center"|6.4
|align="center"|6.4
Line 242: Line 218:
|-
|-
|align="center" width="300" rowspan="2"|Maximum rate of listen() events
|align="center" width="300" rowspan="2"|Maximum rate of listen() events
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|~14
|align="center"|~14
|align="center"|~14
|align="center"|~14
|align="center"|~14
Line 259: Line 233:
|-
|-
|align="center" width="300" rowspan="2"|Maximum rate of sensor() events after llSensorRepeat()
|align="center" width="300" rowspan="2"|Maximum rate of sensor() events after llSensorRepeat()
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|12
|align="center"|12
|align="center"|22
|align="center"|22
|align="center"|22
|align="center"|events/sec
|align="center"|events/sec
Line 275: Line 247:
|align="center" width="300" rowspan="2"|Maximum rate of timer() events
|align="center" width="300" rowspan="2"|Maximum rate of timer() events
Maximum rate of touch() events
Maximum rate of touch() events
|align="center"|LSL classic
|align="center" width="80"|LSL
|align="center"|LSL in Mono Region
|align="center" width="80"|Mono
|align="center"|All Mono
|align="center" width="80"|Units
|align="center" width="80"|Units
|-
|-
|align="center"|22
|align="center"|22
|align="center"|22
|align="center"|22
|align="center"|22

Revision as of 06:43, 23 August 2008

About

I love helping new residents get addicted... er, I mean acclimated to Second Life. Here are some notes I've picked up along the way that might be of help.

SL Glossary

Second Life's most complete glossary

What is Mono?

John and Mary

John and Mary are LSL scripters. John prefers the old-fashioned way of doing things, while Mary enjoys all the latest new technology, like Mono. They both write LSL scripts. John runs his scripts under the old way, and Mary runs hers using Mono.

When John writes an LSL script and clicks the Save button, the client viewer compiles the script into proprietary bytecode and uploads it to the servers. The server runs the script by using a proprietary interpreter to interpret the bytecode. It runs slow.

Mary writes the identical script -- no change in the LSL language syntax. When she presses "Save", the client uploads her script text to the servers where it gets compiled into standardized CIL assembly language. (CIL is a bytecode that originally came from Microsoft's .NET technology.) Because the Linden servers are Linux machines, there's no .NET framework available to run the CIL code. So the servers use the open-source Mono framework to execute the CIL. Mono includes an open-source JIT ("Just in Time") compiler that converts the CIL bytecode into machine code as it's needed, and that compiled machine code is what makes the script execute faster than the old way.

How it all Flows

Old way:

LSL  ---> LSL compiler ---> proprietary bytecode ---> LSL bytecode interpreter

New way:

LSL                        ---> LSL compiler   | 
C# (future)                ---> C# compiler    |  ---> CIL bytecode ---> Mono CIL execution engine
Other languages (future)   ---> other compiler |

Do Scripts Running in Mono Get More Memory?

Yes, it's true that each Mono script gets 64K of memory to use. Non-Mono scripts have to fit inside 16K of memory. (That's compiled code plus stack plus heap.) Unfortunately, Mono-compiled code is a bit of a memory hog and can take up to 4 times as much memory as the old runtime environment. So, scripts using Mono end up with a little more memory to play with depending on the code-to-data ratio, but not four times as much. The advantage to the servers is that small Mono scripts only consume as much server memory as they actually use, while the older LSL virtual machine had to allocate a chunk of 16K of memory to every script regardless of how little memory it actually needed.

Evolving Terminology

LSL - Used to refer to the whole system -- the language, the front-end compiler, and the back-end interpreter. Now it's confusing because it's used in one of two ways and its meaning depends on the context: (1) LSL is the language, the source code, which has not changed with Mono. E.g., "Take this LSL script and compile it with Mono and it will run faster." Or (2) LSL refers to the old compiler front-end and interpreter virtual machine back-end. E.g., "When I compile this script with LSL it runs very slowly." Both meanings are used in the sentence, "This LSL script was compiled with LSL, but that LSL script was compiled with Mono."

Can We Use Other Languages?

Mono just runs CIL bytecode. It doesn't know or care what the original language was. At this time (mid-2008) only LSL source code can be compiled into CIL and run on Mono. But maybe someday we will be able to compile C# and possibly other languages into CIL which will run under Mono. A single object could contain scripts that originally were written in different languages.

The LSL language -- the source syntax -- will probably be supported for a very long time.

However, the servers will support both back-ends for a very long time -- the one that executes the old proprietary LSL bytecode, and the new Mono virtual machine that executes standard CIL. All the millions of existing LSL scripts compiled the old way will continue to run indefinitely. New LSL scripts may be compiled using the old LSL compiler or the new Mono compiler.

What To Expect After Mono Hits the Main Grid

  • Old LSL scripts already compiled: will continue to run indefinitely. You don't have to do a thing.
  • Any LSL script if you have the source code: can be recompiled under the old LSL compiler or the new Mono compiler, at your choice, for a long time to come.
  • C# and other languages: probably added at some future time.


LSL Timings and Rates

Here are some LSL function times and event rates comparing scripts compiled and run using the old LSL toolset and using Mono.

The basic test framework for these tests is to set i to a large value, and take the difference in llGetTime() before and after this loop (the loop is partially unrolled to make the loop control structure overhead negligible), and take several measurements in multiple sims (with sim total frame times < 10 ms) until the numbers converge with a variation of 10% or less:

while (--i >= 0) {
    f(); f(); f(); f(); f(); f(); f(); f();
    f(); f(); f(); f(); f(); f(); f(); f();
}

In a Mono sim, the result of the first run after script reset is ignored to eliminate the overhead of the VM initialization, JIT compilation, etc.

Note that how fast you can call a function doesn't necessarily correspond to how much a function will lag a sim because of all the throttling and scheduling going on inside the run-time engine.

Functions & operators

call to empty f() { } LSL Mono Units
0.33 0.0026 ms/call


v = <PI,PI,PI> + <PI,PI,PI> * PI; LSL Mono Units
0.43 0.022 ms/statement


call to llCSV2List(llList2CSV(x));

where x is a list of 10 integers

LSL Mono Units
3.2 4.0 ms/call


call to llGetInventoryName(INVENTORY_TEXTURE, 0); LSL Mono Units
0.52 0.16 ms/call


call to llGetPos(); LSL Mono Units
0.44 0.047 ms/call


call to llList2Vector(x, 0);

where x = [ ZERO_VECTOR ]

LSL Mono Units
0.55 0.013 ms/call


call to llMD5String(s,0);

where s is a 64-char string

LSL Mono Units
1.4 1.4 ms/call


call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);

One consumer script with empty link_message() { }

LSL Mono Units
1.0 0.90 ms/call

The time it takes to call llMessageLinked() is dependent on the number of consumers of the message, up to about 25-30 consumer scripts. At that point, the time to send a link message becomes constant at one call per 11 or 22.2 ms (yes, the results are bimodal, depending on unknown factors), which is suspiciously similar to 1X or 2X the sim's basic frame rate. See the next test:

call to llMessageLinked(LINK_THIS, 0, "", NULL_KEY);

32 - 64 consumer scripts with empty link_message() { }

LSL Mono Units
11 or 22.2 11 or 22.2 ms/call


call to llSay(-2, "0123456789"); LSL Mono Units
0.9 0.6 ms/call


call to llSubStringIndex(s, "X"); where s is 10000 digits not containing "X" LSL Mono Units
16 22 ms/call


Event handlers

Maximum rate of dataserver() events after llGetNotecardLine() LSL Mono Units
6.4 6.4 events/sec


Maximum rate of listen() events LSL Mono Units
~14 ~14 events/sec

The rate of incoming listen() events seems to be especially sensitive to sim load. It's not easy to get the maximum rate of 14 events/sec.


Maximum rate of sensor() events after llSensorRepeat() LSL Mono Units
12 22 events/sec


Maximum rate of timer() events

Maximum rate of touch() events

LSL Mono Units
22 22 events/sec

About half the sim's basic frame rate of 45 fps.


Links