Difference between revisions of "Mono"

From Second Life Wiki
Jump to navigation Jump to search
m (→‎Enter Mono: H3 promoted to H2 for consistency)
 
(26 intermediate revisions by 13 users not shown)
Line 1: Line 1:
{{Help |Glossary=*}}
{{Help |Glossary=*}}
{| align="right" style="text-align: center" width="375"
| <videoflash>cGoM9p7q1jk</videoflash>
|-
| '''[http://vidtuts.s3.amazonaws.com/Understanding-Mono.mp4 DOWNLOAD this video in high-quality!]''' and<br /> '''[[Mono_demos|watch more videos of Mono in action]]'''
|}
'''"Mono for Second Life" refers to a simulator upgrade which can dramatically speed the running of scripts — especially calculation intensive ones.''' The Linden Scripting Language ( [[LSL Portal | LSL]] ) has not changed in any way<span class="TablePager_nav">[[#FAQ-Differences|*]]</span>, so all of your existing scripted objects and attachments continue to function as before, only now they will have the opportunity to run faster. The key to this improvement is an open-sourced scripting engine called [http://www.mono-project.com/Main_Page Mono].  
'''"Mono for Second Life" refers to a simulator upgrade which can dramatically speed the running of scripts — especially calculation intensive ones.''' The Linden Scripting Language ( [[LSL Portal | LSL]] ) has not changed in any way<span class="TablePager_nav">[[#FAQ-Differences|*]]</span>, so all of your existing scripted objects and attachments continue to function as before, only now they will have the opportunity to run faster. The key to this improvement is an open-sourced scripting engine called [http://www.mono-project.com/Main_Page Mono].  


'''Mono is now live on the main grid with server version 1.24.3'''  
'''Mono is now live on the main grid with server version 1.24.3'''  


You can also check out a '''[http://vidtuts.s3.amazonaws.com/Understanding-Mono.mp4 Torley video turorial]''' or view other '''[[Mono_demos| videos of Mono in action]]'''.


= How LSL scripts work =
<br/>
All your LSL scripts are run by the simulator (Linden Lab server program) that also runs the region you are in. When you teleport, or region cross, your new region's simulator takes on the duty of running all your scripted attachments. But the simulators cannot understand LSL directly -- the language was designed for human readability, not machine. So before the script can be executed, it must be turned into a machine readable format. This process is called compilation, and the resulting machine readable version of the script is called bytecode. LSL scripts are compiled when they are created by resident-programmers. The bytecode itself is stored on the Linden Lab asset servers and never needs to be referred to directly by residents. Instead, when you rez a scripted object, the simulator for the region you are in notes the script(s) in the object, and requests the appropriate bytecode from the asset database. The simulator program has several parts, and the part which runs the script bytecode is called the LSL scripting engine or virtual machine.  
== How LSL scripts work ==
 
Linden Lab server programs, known as ''simulators'' or ''sims'', run all LSL scripts. When you teleport, or region cross, your new region's sim takes on the task of running all your scripted attachments. But a sim cannot understand LSL directly -- the language was designed for human readability, not machine. So before the script can be executed, it must be turned into a machine readable format. This process is called ''compilation'', and the resulting machine-readable version of the script is called ''bytecode''. LSL scripts are compiled when they are created by resident-programmers. The bytecode itself is stored on the Linden Lab asset servers and never needs to be referred to directly by residents. Instead, when you rez a scripted object, the simulator for the region you are in notes the script(s) in the object, and requests the appropriate bytecode from the asset database. The simulator program has several parts, and the part which runs the script bytecode is called the LSL scripting engine or virtual machine.  


In today's Second Life, scripts are everywhere in regions: from simple rotating objects to complicated vehicles, vendors, or attachments that respond to your chat commands. For many regions the scripting engine is kept busy trying to execute hundreds of scripts all at once. As the number and complexity of scripts in a region rises, so do the demands upon the simulator. After a certain point the scripting engine starts taking up so much processing time that the rest of the simulator (particularly the physics engine) bogs down, and server-side lag results. Thus anything that can speed up the execution of scripts can push out the point where server lag starts to occur.
In today's Second Life, scripts are everywhere: from simple rotating objects to complicated vehicles, vendors, or attachments that respond to chat commands. For many regions the scripting engine is kept busy trying to execute hundreds of scripts all at once. As the number and complexity of scripts in a region rises, so do the demands upon the simulator. After a certain point the scripting engine starts taking up so much processing time that the rest of the simulator (particularly the physics engine) bogs down, resulting in server-side lag. Thus, anything that can speed up the execution of scripts can push out the point where server lag starts to occur.


= Enter Mono =
== Enter Mono ==
Mono is another kind of scripting engine. It is fully open-sourced and has a proven record of speed and versatility. For over a year now Mono has been considered by Linden Lab as an alternative to the original scripting engine (sometimes called the LSL2 VM). But there are difficulties with switching engines. The most fundamental problem is that all bytecodes are different. So the LSL bytecode is just gibberish to Mono, and vice versa. Before we could start using a Mono scripting engine, we need to develop a compiler which can take LSL scripts and turn them into Mono bytecode. This is tricky, because the goal is to make scripts running under Mono behave 'exactly' like scripts running under the original engine. It's painstaking work, and requires an extraordinary amount of testing. The final sprint of coding was completed in the third quarter of 2007, and since November Linden Lab QA has been rigorously pounding on the new scripting engine with an assortment of tests both automated and manual.  
[[File:Mono-gorilla.png|frameless|upright=0.25|left|link=https://www.mono-project.com/]][https://www.mono-project.com/ Mono] is an open-source scripting engine with a proven record of speed and versatility. But switching engines requires a compiler that can turn LSL scripts into Mono bytecode. This is tricky, because the goal is to make scripts running under Mono behave exactly like scripts running under the original engine. This desire for backward compatibility required an extraordinary amount of testing.


= The Plan =
== Mono on the main grid ==
Thanks to the efforts of the beta test residents, and the Linden development and QA teams, Mono is now ready for the main grid. The 1.24 server version is Mono enabled, and fully deployed to the main grid as of 29 August 2008.
Thanks to the efforts of the beta test residents, and the Linden development and QA teams, Mono was deployed to the main grid in [[Release_Notes/Second_Life_Server/1.24#Release_Notes_for_Second_Life_Server_1.24.3_.28August_29th.2C_2008.29:| server version 1.24]] on 29 August 2008.


The Mono viewer changes are contained in the 1.21 client, now available as a [http://secondlife.com/support/downloads.php release candidate]. The viewer changes include a checkbox on the script edit dialog (which allows you to make a script compile to Mono), a Tools menu item to allow you to recompile to Mono all the scripts in your selection, and a change to simulator statistics to show events per second instead of instructions per second. Mono requires the 1.21 viewer to create Mono scripts. Note that no special viewer is required to '''run''' Mono scripts -- that is automatic and handled by the server. A Mono viewer is only required in order to change the compile target of a script (from LSL2 to Mono, or vice versa). 
The Mono Viewer changes were first available in the 1.21 client, and are now present in all [http://secondlife.com/corporate/tpv.php allowed] SL viewers. The viewer changes include a checkbox on the script edit dialog (which allows you to make a script compile to Mono), a Tools menu item to allow you to recompile to Mono all the scripts in your selection, and a change to simulator statistics to show events per second instead of instructions per second.  


Another viewer dependency concerns the "Script perf" line in the statistics bar (ctrl-shft-1). In older viewers (1.20 and lower) this line will no longer contain useful data. In 1.21 and later viewers this line becomes "Script events" and gives the number of events handled per second.   
Another viewer dependency concerns the "Script perf" line in the statistics bar (ctrl-shft-1). In older viewers (1.20 and lower) this line will no longer contain useful data. In 1.21 and later viewers this line becomes "Script events" and gives the number of events handled per second.   


Once Mono has been live on the main grid for several months we may turn off compilation to the original scripting engine. At that point all new and edited scripts will be Mono. We will, however, keep the original scripting engine running. This means that old scripts will continue to run as before, but as soon as they are edited they will become Mono scripts.
Once Mono has been live on the main grid for several months Linden Lab may turn off compilation to the original scripting engine. At that point all new and edited scripts will be Mono. However, the servers will also maintain the original scripting engine to enable old scripts to run as before, but run as Mono as soon as they are edited.


= Mono benefits =
== Mono benefits ==
We've run some benchmarks to compare the performance of the original scripting engine and the Mono VM. When we run the tests side by side we found that Mono is up to 220x faster than LSL2. These benchmarks were math intensive scripts usually used to evaluate performance. It should be noted that for ordinary scripts the gains are much more humble.  
Performance benchmark tests show that Mono is up to 220 times faster than LSL2. The benchmarks were math-intensive scripts typically used to evaluate performance. For ordinary scripts, the performance gains are much more humble.


Mono uses more memory than the typical LSL bytecode. It offsets this by introducing dynamic memory allocation. With LSL2, a full 16K is allocated for all scripts, even simple "Hello, Avatar" ones. Mono allocates only the memory it needs. In tests on typical regions it turns out that the combination of Mono using more memory, but allocating memory better, is about a wash as far as overall memory footprint goes.  
Mono uses more memory than the typical LSL bytecode. It offsets this by introducing dynamic memory allocation. LSL2 allocates a full 16KB for all scripts, even simple "Hello, Avatar" ones. Mono allocates only the memory it needs. In tests on typical regions it turns out that the combination of Mono using more memory, but allocating memory better, making it far smaller as the overall memory footprint goes.


In some extreme cases Mono scripts can use up to 4 times the memory as LSL2 scripts. In order to maintain backwards compatibility the script size limit has been increased from 16K to 64K.
In some extreme cases Mono scripts can use up to four times the memory as LSL2 scripts. To maintain backwards compatibility, the script size limit has been increased from 16KB to 64KB.


Mono tip:
'''Mono tip:'''
Mono can do bytecode sharing. Thus multiple copies of scripts with the same asset id will only take up as much room as one instance. Imagine some script that you use a dozen times on your land. If each of the objects containing the script is separately compiled from text source, you will use up a dozen times the script's size of memory. But if instead you simply drag a copy of the single, already compiled script into each of the dozen objects, then no matter how many copies exist they only take up the size of one script (plus data) in memory.
Mono can do bytecode sharing. Thus multiple copies of scripts with the same asset id will only take up as much room as one instance. Imagine some script that you use a dozen times on your land. If each of the objects containing the script is separately compiled from text source, you will use up a dozen times the script's size of memory. But if instead you simply drag a copy of the single, already compiled script into each of the dozen objects, then no matter how many copies exist they only take up the size of one script (plus data) in memory.


= Mono How-to =
== How to use Mono ==


Mono is now fully deployed to the main grid with server 1.24.3. All regions can now run scripts compiled to Mono. You need a viewer versioned 1.21 or later to compile scripts to Mono, however no special viewer is needed to run previously compiled Mono scripts.  
Mono is now fully deployed to the main grid with server 1.24.3. All allowed SL viewers have the interface to create Mono scripts.  


* '''Download a viewer with the Mono UI if you want to create Mono scripts'''
* '''Log in to Second Life with a Release or Release Candidate viewer'''
** The 1.21 viewer is available in release candidate. See the Test Viewers section of the [http://secondlife.com/support/downloads.php downloads page].
* '''Log in to SL and go to a Mono-enabled region'''
** All regions are Mono-enabled as of 29 August 2008
** Blog: http://blog.secondlife.com/2008/08/20/mono-launch/
** Release notes: https://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Server/1.24
** Forum thread, for comments: http://forums.secondlife.com/showthread.php?p=2115465
* '''Create/edit a script and compile it to Mono'''
* '''Create/edit a script and compile it to Mono'''
** Create an object and add a new script to it
** Create an object and add a new script to it
Line 50: Line 52:
** Hit Save to recompile this script to Mono.
** Hit Save to recompile this script to Mono.
** You may now treat this script like any other. It will automatically run in the Mono runtime, regardless of ownership transfers or viewer version.
** You may now treat this script like any other. It will automatically run in the Mono runtime, regardless of ownership transfers or viewer version.
** If you fail to see the checkbox, you are not running a Mono viewer.
** If the checkbox is grayed out for Mono, you are not in a Mono enabled region.
** To convert a Mono script back to ordinary LSL2, uncheck the checkbox.
** To convert a Mono script back to ordinary LSL2, uncheck the checkbox.
* '''To convert a number of scripted objects all to Mono at once'''
* '''To convert a number of scripted objects all to Mono at once'''
Line 61: Line 61:


'''To report Mono issues, use JIRA'''
'''To report Mono issues, use JIRA'''
* First check [https://jira.secondlife.com/browse/SVC-1276 this meta JIRA] to see if anyone has reported the issue already
* Public JIRA [https://jira.secondlife.com/secure/CreateIssue!default.jspa create issue]
** This may not be doable unless you've drilled down into your script to locate what is breaking.
* If an issue already exists, and it appears to be the same failure, then simply add your information as a comment and attachment to that issue.
* If a JIRA already exists, and it appears to be the same failure, then simply add your information as a comment and attachment to that issue.
* If not, open a new SVC ticket for each bug you find. In the ticket summary please use the word "Mono" so that we can filter for them.  
* If not, open a new SVC ticket for each bug you find. In the ticket summary please use the word "Mono" so that we can filter for them.  
* In addition to your description of the problem please attach your script itself, or (ideally) a smaller script which illustrates the difference in behavior between the two scripting engines.
* In addition to your description of the problem please attach your script itself, or (ideally) a smaller script which illustrates the difference in behavior between the two scripting engines.
* Link your JIRA to the meta JIRA.
* Link your JIRA to the meta JIRA.


= Testing =
== Testing ==
During the integration of Mono we have used tests to ensure there are no regressions. For the current version of the regression test see [[LSL Language Test]]. This effectively serves as the specification of LSL.
During the integration of Mono we have used tests to ensure there are no regressions. For the current version of the regression test see [[LSL Language Test]]. This effectively serves as the specification of LSL.


Line 82: Line 81:
*[[LSL NSieve Bits Benchmark]]
*[[LSL NSieve Bits Benchmark]]


= FAQ =
== FAQs ==
Section for questions.
 
; Can you give a few examples scripts where Mono's speed increase is readily apparent? : These calculation intensive scripts run considerably faster under Mono: [[LSL_Recursion_Benchmark]], [[LSL_Mandelbrot_Benchmark]], [[LSL_Partial_Sums_Benchmark]],[[LSL_NSieve_Benchmark]], [[LSL_NSieve_Bits_Benchmark]].
----
; As far as previously purchased LSL scripts, why do I have to wait for the scripter to convert the script to run on Mono, why can’t I just do this myself? : The increase in speed provided by Mono can cause problems with objects using communication between multiple scripts and there are a few cases where we have had to make Mono behave slightly differently to LSL. It's much safer to have the original scripter convert and '''test''' the scripts.
; '''Can you give a few example scripts where Mono's speed increase is readily apparent?''' : These calculation intensive scripts run considerably faster under Mono: [[LSL_Recursion_Benchmark]], [[LSL_Mandelbrot_Benchmark]], [[LSL_Partial_Sums_Benchmark]], [[LSL_NSieve_Benchmark]], [[LSL_NSieve_Bits_Benchmark]].
; Will scripts compiled to Mono work on an older version of the viewer? : Yes. You only need a viewer version 1.21 or later if you want to make Mono scripts. You can run Mono scripts from any viewer since Mono actually runs on the server.
 
; How long until scripts can be compiled to Mono? : The 1.21 viewer release candidate should be available on Wednesday, 20 August.
; '''As far as previously purchased LSL scripts, why do I have to wait for the scripter to convert the script to run on Mono, why can’t I just do this myself?''' : The increase in speed provided by Mono can cause problems with objects using communication between multiple scripts and there are a few cases where we have had to make Mono behave slightly differently to LSL. It's much safer to have the original scripter convert and '''test''' the scripts.
; Is there an indicator of some kind to tell me that a script is running on Mono? How can I tell? : No. It's very difficult to work out whether objects and all the objects they contain use Mono scripts, so we haven't attempted to display it.  
 
; Given that OpenSim runs on Mono, will LL implementing Mono expedite interoperability between the two worlds? : We are talking to OpenSim developers about script interoperability based on Mono.
; '''Will scripts compiled to Mono work on an older version of the viewer?''' : Yes. You only need a viewer version 1.21 or later if you want to make Mono scripts. You can run Mono scripts from any viewer since Mono actually runs on the server.
; Has the available memory for scripts changed? (Currently 16k in LSL2 VM) : For the same LSL script the Mono bytecode and original (LSL2) bytecode will be of different size. In order to be compatible with all known scripts, we have expanded the size ceiling for Mono to be 64k. This is ok to do for Mono because unlike LSL2, Mono allocates memory dynamically, whereas all LSL2 scripts occupy 16K. Mono scripts only allocate the memory that they need.
 
; 64K? Wow, isn't that going to encourage inefficient scripting? : We hope that the change will promote more efficient scripting. Currently programmers have to get around the 16K limit by using multiple scripts, and a lot of cycles get spent on passing data between those scripts. With a single script that would not be necessary.  
; '''Is there an indicator of some kind to tell me that a script is running on Mono? How can I tell?''' : No. It's very difficult to work out whether objects and all the objects they contain use Mono scripts, so we haven't attempted to display it.
; Are there other ways to make my scripts even more memory efficient when using Mono? : Indeed, Mono can do what's called bytecode sharing. Suppose you have a region which uses many instances of the same script, like XYText or Puppeteer, for example. As long as all the instances share the same asset id, the bytecode will only be added to memory once, and shared by all the copies. Key to making this work is ensuring that you simply copy the scripts (or the objects the scripts are within) after they have been saved for the final time. If you have purchased a script that is used many times, ask the creator for a Mono version, and then copy that version into the objects. It's important that you copy the scripts, so that the asset id is the same. If you recompile each instance separately, they will get different asset ids and the engine won't be able to share the bytecode.  
 
; Will I have to manually convert all my objects to using Mono, or is there an automated tool? : Yes, you must manually invoke compilation to Mono. Though you can make use of the Tools Menu to recompile all scripts in selection to Mono.  
; '''Given that OpenSim runs on Mono, will LL implementing Mono expedite interoperability between the two worlds?''' : We are talking to OpenSim developers about script interoperability based on Mono.
; Can I keep my scripts running on the original scripting engine forever? : We have no plans to eliminate the original engine. This will be re-examined after Mono has been live on the Main Grid for a while. But right now it is easier to continue to support the original scripting engine than to migrate all scripts.  
 
; Will I be able to write scripts in languages besides LSL since Mono supports lots of languages? : Eventually. Right now our goal is to make Mono completely compatible with the original scripting engine for LSL scripts.
; '''Has the available memory for scripts changed?''' ''(Currently 16k in LSL2 VM)'' : For the same LSL script the Mono bytecode and original (LSL2) bytecode will be of different size. In order to be compatible with all known scripts, we have expanded the size ceiling for Mono to be 64k. This is ok to do for Mono because unlike LSL2, Mono allocates memory dynamically, whereas all LSL2 scripts occupy 16K. Mono scripts only allocate the memory that they need.
; Will LSL be getting real language features with this change? (ie arrays, references/pointers, includes/imports)
 
: No.  The LSL language is not changing with this update.
; '''64K? Wow, isn't that going to encourage inefficient scripting?''' : We hope that the change will promote more efficient scripting. Currently programmers have to get around the 16K limit by using multiple scripts, and a lot of cycles get spent on passing data between those scripts. With a single script that would not be necessary.
; In the original scripting engine scripts are compiled on the viewer then uploaded, will that change with Mono? : Yes, Mono compilation is done in a distributed fashion on the sim hosts.  
 
; Related to the above, I use a "clever trick" to upload my compiled bytecode in LSL2 with out the correct script text. What will happen to scripts I uploaded in this way when converted to Mono? Will I be able to continue to use my "clever trick" for Mono scripts? : The Mono compiler looks only at the script text. The Mono engine will only run bytecode which has been compiled by our Mono compiler. You will not be able to run any uploaded Mono bytecode.
; '''Are there other ways to make my scripts even more memory efficient when using Mono?''' : Indeed, Mono can do what's called bytecode sharing. Suppose you have a region which uses many instances of the same script, like XYText or Puppeteer, for example. As long as all the instances share the same asset id, the bytecode will only be added to memory once, and shared by all the copies. Key to making this work is ensuring that you simply copy the scripts (or the objects the scripts are within) after they have been saved for the final time. If you have purchased a script that is used many times, ask the creator for a Mono version, and then copy that version into the objects. It's important that you copy the scripts, so that the asset id is the same. If you recompile each instance separately, they will get different asset ids and the engine won't be able to share the bytecode.
; What about scripts whose LSL code has been lost, ie scripts that still run, but result in "Script missing from database." when you try to edit them?  Is there any possibility of bytecode translation, or are these scripts stuck in the original scripting engine forever?
 
: There are currently no plans to allow byte code translation of LSL scripts, only compiling from source. This may be considered depending on resident demand.
; '''Will I have to manually convert all my objects to using Mono, or is there an automated tool?''' : Yes, you must manually invoke compilation to Mono. Though you can make use of the Tools Menu to recompile all scripts in selection to Mono.
; <span id="FAQ-Differences"></span>What are the known differences between the LSL2 and Mono compilers and runtimes?
 
; '''Can I keep my scripts running on the original scripting engine forever?''' : We have no plans to eliminate the original engine. This will be re-examined after Mono has been live on the Main Grid for a while. But right now it is easier to continue to support the original scripting engine than to migrate all scripts.
 
; '''Will I be able to write scripts in languages besides LSL since Mono supports lots of languages?''' : Eventually. Right now our goal is to make Mono completely compatible with the original scripting engine for LSL scripts.
 
; '''Will LSL be getting real language features with this change?''' (ie arrays, references/pointers, includes/imports) : No.  The LSL language is not changing with this update.
 
; '''In the original scripting engine scripts are compiled on the viewer then uploaded, will that change with Mono?''' : Yes, Mono compilation is done in a distributed fashion on the sim hosts.
 
; '''Related to the above, I use a "clever trick" to upload my compiled bytecode in LSL2 with out the correct script text. What will happen to scripts I uploaded in this way when converted to Mono? Will I be able to continue to use my "clever trick" for Mono scripts?''' : The Mono compiler looks only at the script text. The Mono engine will only run bytecode which has been compiled by our Mono compiler. You will not be able to run any uploaded Mono bytecode.
 
; '''What about ''bytecode'' scripts whose ''LSL code'' has been lost, ie scripts that still run, but result in "Script missing from database." when you try to edit them?  Is there any possibility of bytecode translation, or are these scripts stuck in the original scripting engine forever?''' : There are currently no plans to allow byte code translation of LSL scripts, only compiling from source. This may be considered depending on Resident demand.
 
; <span id="FAQ-Differences"></span>'''What are the known differences between the LSL2 and Mono compilers and runtimes?'''
: We have not tried to make Mono 100% compatible with the original engine. At least not to the point of duplicating any of the tricks or hacks that LSL2 allowed. Below are listed some known behavioral differences. Add to the list as more are discovered.
: We have not tried to make Mono 100% compatible with the original engine. At least not to the point of duplicating any of the tricks or hacks that LSL2 allowed. Below are listed some known behavioral differences. Add to the list as more are discovered.
:* Unicode support. From Strife Onizuka "In LSO LSL, the entire Unicode range was supported by complying to RFC 2279 (about 2 billion possible characters). Mono supports RFC 3629 which supplants RFC 2279 and limits the Unicode range to the first 1,114,112 character codes. This directly effects these functions: [[llBase64ToString]], [[llUnescapeURL]]. Strings being passed from LSO scripts to Mono scripts will become corrupted (in a reliable way) if they contain characters outside the limited Unicode range." -- {{Jira|SVC-1960}}
:* Unicode support. From Strife Onizuka "In LSO LSL, the entire Unicode range was supported by complying to RFC 2279 (about 2 billion possible characters). Mono supports RFC 3629 which supplants RFC 2279 and limits the Unicode range to the first 1,114,112 character codes. This directly effects these functions: [[llBase64ToString]], [[llUnescapeURL]]. Strings being passed from LSO scripts to Mono scripts will become corrupted (in a reliable way) if they contain characters outside the limited Unicode range." -- {{Jira|SVC-1960}}
; <span id="FAQ-Recompile"></span>After Mono launches why not recompile *all* scripts everywhere on the Grid to Mono?
 
:* Dividing by zero - LSL2 errors on divide by zero, Mono uses value "Infinity" and does not error. ''Under server 1.30, this is an error under both environments, watch {{Jira|SVC-4805}} for updates.''
; <span id="FAQ-Recompile"></span>'''After Mono launches why not recompile *all* scripts everywhere on the Grid to Mono?'''
: While it is certainly appealing to have only one compiler and runtime to support, practical concerns make this not feasible. Here's a list of the difficulties that give us pause:
: While it is certainly appealing to have only one compiler and runtime to support, practical concerns make this not feasible. Here's a list of the difficulties that give us pause:
:* We do not have the text asset (the LSL code) for all running scripts. These "bytecode only" scripts would stop working.
:* We do not have the text asset (the LSL code) for all running scripts. These "bytecode only" scripts would stop working.
:* The automatic recompile would restart all scripts. Many scripts are meant to run continuously without restarting.
:* The automatic recompile would restart all scripts. Many scripts are meant to run continuously without restarting.
:* Mono scripts have a different timing profile than the original (usually faster). This will introduce behavior differences which will lead to some scripts breaking, often in subtle ways.
:* Mono scripts have a different timing profile than the original (usually faster). This will introduce behavior differences which will lead to some scripts breaking, often in subtle ways.
:* Some scripts take advantage of undocumented "features" of LSL2. We did not strive for 100% compatibility in such situations, but rather made Mono behave as sensibly and predictably as possible.
:* Some scripts take advantage of undocumented "features" of LSL2. We did not strive for 100% compatibility in such situations, but rather made Mono behave as sensibly and predictably as possible.
:* As a result of both reasons above, scripts need QA work after they have been recompiled. Residents who code and sell LSL scripts will have to test and possibly adjust the behavior of Mono versions of their scripts. If conversion were automatic they would not be reimbursed for their QA effort. With manual recompilation the resident scripters can sell Mono versions of their scripts as an upgrade, after they have tested and modified them.  
 
:* Recompiling all scripts would play rather heavy-handedly with the permissions system. If someone has made and sold a script as "no-modify", an automatic recompilation would violate their policy. While some scripters would be ok with this, many would not.
:* As a result of both reasons above, scripts need QA work after they have been recompiled. Residents who code and sell LSL scripts will have to test and possibly adjust the behavior of Mono versions of their scripts. If conversion were automatic they would not be reimbursed for their QA effort. With manual recompilation the Resident scripters can sell Mono versions of their scripts as an upgrade, after they have tested and modified them.  
; Is Mono still available on the preview grid? : Yes, see [[Mono/Beta FAQ]].
 
:* Recompiling all scripts would play rather heavy-handedly with the permissions system. If someone has made and sold a script as "no-modify", an automatic recompilation would violate their policy. While some scripters would be ok with this, many would not.
 
; '''Is Mono still available on the preview grid?''' : Yes, see [[Mono/Beta FAQ]].
 
== Mono Memory Myths ==
'''NOTE:''' The following has been commented on since by the OpenSim wiki - Miguel was testing an idle region without any background activity or users. It is not a representitive test. See more at [http://opensimulator.org/wiki/Mono]
 
Experience with Mono in Opensim has led to the widespread belief that Mono on Linux is an extreme memory hog compared to .NET on MS Windows.  This belief has been countered by the creator of Mono, [http://en.wikipedia.org/wiki/Miguel_de_Icaza Miguel de Icaza], after he performed direct tests on 14th June 2009 in Vista 32, Linux 32, and Linux 64.  His results and advice were posted on [http://pastebin.ca/1460383 pastebin], and are repeated here since that site is not intended for persistent publication:
 
A third follow up.
With the help from the guys on #opensim on irc.freenode.org I got myself a sample virtual world from:
http://opensimworlds.com/index.php?part=worlds
I used "Nu Athens" a free download and loaded it up on 3 configurations:
Vista, running 32 bit OpenSim
Linux, running 64 bit OpenSim
Linux, running 32 bit OpenSim
And then I loaded all the four files provided in the zip file using the command:
load oar FILE.tar.gz
The results are as follows:
Vista/32: 115 megs + 5 meg helper process (OpenSim.vhost.exe)
Mono/32: 92 megs, after a few minutes of inactivity, it goes down to 87 megs.
Mono/64: 122 megs, after a few minutes of inactivity, it goes down to 89 megs. 
The garbage collector is responsible for the difference in memory usage between the load finished
and waiting (I ran into this problem because I came to measure again after a few seconds and the
size had been reduced).
The Vista system remains at 120 megs total for the same world.
So Mono on Linux on both 32 and 64 bit configurations is consuming less memory than Vista, some
40 megs out of 120, or one third less memory.
Perhaps the difference is in the version of Mono that we are running.  I am running with Mono 2.4,
and the OpenSim documentation implies that OpenSim can work with systems like Mono 1.2.6 which is
primitive by our standards (that was released more than two years ago).
In Mono 2.0, Mono 2.2 and Mono 2.4 we introduced many memory reduction features.  From using
precise collection for the HEAP, to reducing the size of generics-heavy code to reduction in code
size generated and runtime metadata tables.
I would appreciate if you could post a correction to your data in the main article, as it seems to
have spread and this could negatively impact the perception of the Mono's community work towards
making a great .NET implementation for Unix.
Miguel
 
* PS. Miguel is measuring RSS (not VSIZE), for reasons explained [http://opensimulator.org/wiki/Talk:Mono in an earlier post].


[[Category:Features]]
[[Category:Features]]
[[Category:Performance and stability]]

Latest revision as of 06:25, 24 September 2022

<videoflash>cGoM9p7q1jk</videoflash>
DOWNLOAD this video in high-quality! and
watch more videos of Mono in action

"Mono for Second Life" refers to a simulator upgrade which can dramatically speed the running of scripts — especially calculation intensive ones. The Linden Scripting Language ( LSL ) has not changed in any way*, so all of your existing scripted objects and attachments continue to function as before, only now they will have the opportunity to run faster. The key to this improvement is an open-sourced scripting engine called Mono.

Mono is now live on the main grid with server version 1.24.3



How LSL scripts work

Linden Lab server programs, known as simulators or sims, run all LSL scripts. When you teleport, or region cross, your new region's sim takes on the task of running all your scripted attachments. But a sim cannot understand LSL directly -- the language was designed for human readability, not machine. So before the script can be executed, it must be turned into a machine readable format. This process is called compilation, and the resulting machine-readable version of the script is called bytecode. LSL scripts are compiled when they are created by resident-programmers. The bytecode itself is stored on the Linden Lab asset servers and never needs to be referred to directly by residents. Instead, when you rez a scripted object, the simulator for the region you are in notes the script(s) in the object, and requests the appropriate bytecode from the asset database. The simulator program has several parts, and the part which runs the script bytecode is called the LSL scripting engine or virtual machine.

In today's Second Life, scripts are everywhere: from simple rotating objects to complicated vehicles, vendors, or attachments that respond to chat commands. For many regions the scripting engine is kept busy trying to execute hundreds of scripts all at once. As the number and complexity of scripts in a region rises, so do the demands upon the simulator. After a certain point the scripting engine starts taking up so much processing time that the rest of the simulator (particularly the physics engine) bogs down, resulting in server-side lag. Thus, anything that can speed up the execution of scripts can push out the point where server lag starts to occur.

Enter Mono

Mono-gorilla.png

Mono is an open-source scripting engine with a proven record of speed and versatility. But switching engines requires a compiler that can turn LSL scripts into Mono bytecode. This is tricky, because the goal is to make scripts running under Mono behave exactly like scripts running under the original engine. This desire for backward compatibility required an extraordinary amount of testing.

Mono on the main grid

Thanks to the efforts of the beta test residents, and the Linden development and QA teams, Mono was deployed to the main grid in server version 1.24 on 29 August 2008.

The Mono Viewer changes were first available in the 1.21 client, and are now present in all allowed SL viewers. The viewer changes include a checkbox on the script edit dialog (which allows you to make a script compile to Mono), a Tools menu item to allow you to recompile to Mono all the scripts in your selection, and a change to simulator statistics to show events per second instead of instructions per second.

Another viewer dependency concerns the "Script perf" line in the statistics bar (ctrl-shft-1). In older viewers (1.20 and lower) this line will no longer contain useful data. In 1.21 and later viewers this line becomes "Script events" and gives the number of events handled per second.

Once Mono has been live on the main grid for several months Linden Lab may turn off compilation to the original scripting engine. At that point all new and edited scripts will be Mono. However, the servers will also maintain the original scripting engine to enable old scripts to run as before, but run as Mono as soon as they are edited.

Mono benefits

Performance benchmark tests show that Mono is up to 220 times faster than LSL2. The benchmarks were math-intensive scripts typically used to evaluate performance. For ordinary scripts, the performance gains are much more humble.

Mono uses more memory than the typical LSL bytecode. It offsets this by introducing dynamic memory allocation. LSL2 allocates a full 16KB for all scripts, even simple "Hello, Avatar" ones. Mono allocates only the memory it needs. In tests on typical regions it turns out that the combination of Mono using more memory, but allocating memory better, making it far smaller as the overall memory footprint goes.

In some extreme cases Mono scripts can use up to four times the memory as LSL2 scripts. To maintain backwards compatibility, the script size limit has been increased from 16KB to 64KB.

Mono tip: Mono can do bytecode sharing. Thus multiple copies of scripts with the same asset id will only take up as much room as one instance. Imagine some script that you use a dozen times on your land. If each of the objects containing the script is separately compiled from text source, you will use up a dozen times the script's size of memory. But if instead you simply drag a copy of the single, already compiled script into each of the dozen objects, then no matter how many copies exist they only take up the size of one script (plus data) in memory.

How to use Mono

Mono is now fully deployed to the main grid with server 1.24.3. All allowed SL viewers have the interface to create Mono scripts.

  • Log in to Second Life with a Release or Release Candidate viewer
  • Create/edit a script and compile it to Mono
    • Create an object and add a new script to it
    • Edit the script from the object's contents tab.
    • On the script editing dialog you will see a new checkbox at the bottom "Mono". Check it.
    • Hit Save to recompile this script to Mono.
    • You may now treat this script like any other. It will automatically run in the Mono runtime, regardless of ownership transfers or viewer version.
    • To convert a Mono script back to ordinary LSL2, uncheck the checkbox.
  • To convert a number of scripted objects all to Mono at once
    • Rez all the scripted objects
    • Use the select tool to select them all.
    • From the Tools menu select Recompile Selection / Mono.

After you have converted a scripted object to Mono you will need to do a full QA run. Though Mono is compatible with old LSL2, there are timing differences which may cause object behavioral changes. Test your objects thoroughly before releasing Mono versions.

To report Mono issues, use JIRA

  • Public JIRA create issue
  • If an issue already exists, and it appears to be the same failure, then simply add your information as a comment and attachment to that issue.
  • If not, open a new SVC ticket for each bug you find. In the ticket summary please use the word "Mono" so that we can filter for them.
  • In addition to your description of the problem please attach your script itself, or (ideally) a smaller script which illustrates the difference in behavior between the two scripting engines.
  • Link your JIRA to the meta JIRA.

Testing

During the integration of Mono we have used tests to ensure there are no regressions. For the current version of the regression test see LSL Language Test. This effectively serves as the specification of LSL.

There are tests for library call bindings in LSL Library Call Test 1 and LSL Library Call Test 2. This is split to overcome the memory limitations.

Event test script

There are several benchmarks to test the performance. They are available here:

FAQs


Can you give a few example scripts where Mono's speed increase is readily apparent?
These calculation intensive scripts run considerably faster under Mono: LSL_Recursion_Benchmark, LSL_Mandelbrot_Benchmark, LSL_Partial_Sums_Benchmark, LSL_NSieve_Benchmark, LSL_NSieve_Bits_Benchmark.
As far as previously purchased LSL scripts, why do I have to wait for the scripter to convert the script to run on Mono, why can’t I just do this myself?
The increase in speed provided by Mono can cause problems with objects using communication between multiple scripts and there are a few cases where we have had to make Mono behave slightly differently to LSL. It's much safer to have the original scripter convert and test the scripts.
Will scripts compiled to Mono work on an older version of the viewer?
Yes. You only need a viewer version 1.21 or later if you want to make Mono scripts. You can run Mono scripts from any viewer since Mono actually runs on the server.
Is there an indicator of some kind to tell me that a script is running on Mono? How can I tell?
No. It's very difficult to work out whether objects and all the objects they contain use Mono scripts, so we haven't attempted to display it.
Given that OpenSim runs on Mono, will LL implementing Mono expedite interoperability between the two worlds?
We are talking to OpenSim developers about script interoperability based on Mono.
Has the available memory for scripts changed? (Currently 16k in LSL2 VM)
For the same LSL script the Mono bytecode and original (LSL2) bytecode will be of different size. In order to be compatible with all known scripts, we have expanded the size ceiling for Mono to be 64k. This is ok to do for Mono because unlike LSL2, Mono allocates memory dynamically, whereas all LSL2 scripts occupy 16K. Mono scripts only allocate the memory that they need.
64K? Wow, isn't that going to encourage inefficient scripting?
We hope that the change will promote more efficient scripting. Currently programmers have to get around the 16K limit by using multiple scripts, and a lot of cycles get spent on passing data between those scripts. With a single script that would not be necessary.
Are there other ways to make my scripts even more memory efficient when using Mono?
Indeed, Mono can do what's called bytecode sharing. Suppose you have a region which uses many instances of the same script, like XYText or Puppeteer, for example. As long as all the instances share the same asset id, the bytecode will only be added to memory once, and shared by all the copies. Key to making this work is ensuring that you simply copy the scripts (or the objects the scripts are within) after they have been saved for the final time. If you have purchased a script that is used many times, ask the creator for a Mono version, and then copy that version into the objects. It's important that you copy the scripts, so that the asset id is the same. If you recompile each instance separately, they will get different asset ids and the engine won't be able to share the bytecode.
Will I have to manually convert all my objects to using Mono, or is there an automated tool?
Yes, you must manually invoke compilation to Mono. Though you can make use of the Tools Menu to recompile all scripts in selection to Mono.
Can I keep my scripts running on the original scripting engine forever?
We have no plans to eliminate the original engine. This will be re-examined after Mono has been live on the Main Grid for a while. But right now it is easier to continue to support the original scripting engine than to migrate all scripts.
Will I be able to write scripts in languages besides LSL since Mono supports lots of languages?
Eventually. Right now our goal is to make Mono completely compatible with the original scripting engine for LSL scripts.
Will LSL be getting real language features with this change? (ie arrays, references/pointers, includes/imports)
No. The LSL language is not changing with this update.
In the original scripting engine scripts are compiled on the viewer then uploaded, will that change with Mono?
Yes, Mono compilation is done in a distributed fashion on the sim hosts.
Related to the above, I use a "clever trick" to upload my compiled bytecode in LSL2 with out the correct script text. What will happen to scripts I uploaded in this way when converted to Mono? Will I be able to continue to use my "clever trick" for Mono scripts?
The Mono compiler looks only at the script text. The Mono engine will only run bytecode which has been compiled by our Mono compiler. You will not be able to run any uploaded Mono bytecode.
What about bytecode scripts whose LSL code has been lost, ie scripts that still run, but result in "Script missing from database." when you try to edit them? Is there any possibility of bytecode translation, or are these scripts stuck in the original scripting engine forever?
There are currently no plans to allow byte code translation of LSL scripts, only compiling from source. This may be considered depending on Resident demand.
What are the known differences between the LSL2 and Mono compilers and runtimes?
We have not tried to make Mono 100% compatible with the original engine. At least not to the point of duplicating any of the tricks or hacks that LSL2 allowed. Below are listed some known behavioral differences. Add to the list as more are discovered.
  • Unicode support. From Strife Onizuka "In LSO LSL, the entire Unicode range was supported by complying to RFC 2279 (about 2 billion possible characters). Mono supports RFC 3629 which supplants RFC 2279 and limits the Unicode range to the first 1,114,112 character codes. This directly effects these functions: llBase64ToString, llUnescapeURL. Strings being passed from LSO scripts to Mono scripts will become corrupted (in a reliable way) if they contain characters outside the limited Unicode range." -- SVC-1960
  • Dividing by zero - LSL2 errors on divide by zero, Mono uses value "Infinity" and does not error. Under server 1.30, this is an error under both environments, watch SVC-4805 for updates.
After Mono launches why not recompile *all* scripts everywhere on the Grid to Mono?
While it is certainly appealing to have only one compiler and runtime to support, practical concerns make this not feasible. Here's a list of the difficulties that give us pause:
  • We do not have the text asset (the LSL code) for all running scripts. These "bytecode only" scripts would stop working.
  • The automatic recompile would restart all scripts. Many scripts are meant to run continuously without restarting.
  • Mono scripts have a different timing profile than the original (usually faster). This will introduce behavior differences which will lead to some scripts breaking, often in subtle ways.
  • Some scripts take advantage of undocumented "features" of LSL2. We did not strive for 100% compatibility in such situations, but rather made Mono behave as sensibly and predictably as possible.
  • As a result of both reasons above, scripts need QA work after they have been recompiled. Residents who code and sell LSL scripts will have to test and possibly adjust the behavior of Mono versions of their scripts. If conversion were automatic they would not be reimbursed for their QA effort. With manual recompilation the Resident scripters can sell Mono versions of their scripts as an upgrade, after they have tested and modified them.
  • Recompiling all scripts would play rather heavy-handedly with the permissions system. If someone has made and sold a script as "no-modify", an automatic recompilation would violate their policy. While some scripters would be ok with this, many would not.
Is Mono still available on the preview grid?
Yes, see Mono/Beta FAQ.

Mono Memory Myths

NOTE: The following has been commented on since by the OpenSim wiki - Miguel was testing an idle region without any background activity or users. It is not a representitive test. See more at [1]

Experience with Mono in Opensim has led to the widespread belief that Mono on Linux is an extreme memory hog compared to .NET on MS Windows. This belief has been countered by the creator of Mono, Miguel de Icaza, after he performed direct tests on 14th June 2009 in Vista 32, Linux 32, and Linux 64. His results and advice were posted on pastebin, and are repeated here since that site is not intended for persistent publication:

A third follow up.

With the help from the guys on #opensim on irc.freenode.org I got myself a sample virtual world from:

http://opensimworlds.com/index.php?part=worlds

I used "Nu Athens" a free download and loaded it up on 3 configurations:

Vista, running 32 bit OpenSim
Linux, running 64 bit OpenSim
Linux, running 32 bit OpenSim

And then I loaded all the four files provided in the zip file using the command:

load oar FILE.tar.gz

The results are as follows:

Vista/32: 115 megs + 5 meg helper process (OpenSim.vhost.exe)

Mono/32: 92 megs, after a few minutes of inactivity, it goes down to 87 megs.

Mono/64: 122 megs, after a few minutes of inactivity, it goes down to 89 megs.   

The garbage collector is responsible for the difference in memory usage between the load finished
and waiting (I ran into this problem because I came to measure again after a few seconds and the
size had been reduced).

The Vista system remains at 120 megs total for the same world.

So Mono on Linux on both 32 and 64 bit configurations is consuming less memory than Vista, some
40 megs out of 120, or one third less memory.

Perhaps the difference is in the version of Mono that we are running.  I am running with Mono 2.4,
and the OpenSim documentation implies that OpenSim can work with systems like Mono 1.2.6 which is
primitive by our standards (that was released more than two years ago).

In Mono 2.0, Mono 2.2 and Mono 2.4 we introduced many memory reduction features.   From using
precise collection for the HEAP, to reducing the size of generics-heavy code to reduction in code
size generated and runtime metadata tables.

I would appreciate if you could post a correction to your data in the main article, as it seems to
have spread and this could negatively impact the perception of the Mono's community work towards
making a great .NET implementation for Unix.

Miguel