multiverse stm for in-memory datastructures done (with one bug left to do)

This commit is contained in:
Jonas Boner 2009-08-15 22:44:29 +02:00
parent ce02e9f8be
commit 8e55322d53
266 changed files with 5228 additions and 4552 deletions

0
LICENSE Normal file → Executable file
View file

0
README.textile Normal file → Executable file
View file

0
akka.iml Normal file → Executable file
View file

3655
akka.ipr Normal file → Executable file

File diff suppressed because it is too large Load diff

4703
akka.iws Normal file → Executable file

File diff suppressed because it is too large Load diff

0
buildfile Normal file → Executable file
View file

View file

@ -0,0 +1,6 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 10.0-b22 (Sun Microsystems Inc.)
Premain-Class: org.multiverse.standard.instrumentation.MultiverseJavaA
gent

View file

@ -0,0 +1,192 @@
---------------- Faster Get-Transactie optimizations -----------------
De huidige transactie moet opgehaald worden via de ThreadLocal. Dit kan een kostbare aangelegenheid worden,
dus de vraag is hoe je dit kunt optimaliseren:
voor:
int get(){
$IntValue tranlocalThis = ($IntValue)TransactionThreadLocal.get().read(this);
return tranlocalThis;
}
void foo(){
Transaction t = startTransaction();
someIntValue.get();
t.commit();
}
Kosten zijn nu 1 getTransaction.
na:
int get(Transaction t){
$IntValue tranlocalThis = ($IntValue)t.read(this);
return tranlocalThis;
}
void foo(){
Transaction t = startTransaction();
someIntValue.get(t);
t.commit();
}
Kosten zijn nu 0 getTransaction.
Wat:
Je zult de signature van de methode breder moeten maken zodat de transaction meegegeven gaat worden.
Je zult aanroepende methodes ook breder moeten maken.
Wanneer:
Tot hoe diep ga je.
Note:
Volgens mij is dit een vrij eenvoudige optimalisatie aangezien je niets hoeft te weten van de andere classes.
Als er extra methodes bij worden gegenereerd, kan je gewoon de huidige methode aanroepen vervangen
----------------- Optimization ---------------------------
Methods that don't need a transaction..
doel"
verminderen overhead transactie creatie/administratie.
-------------- Optimization -----------------------------
probleem:
Als een object bewerkingen gaat doen op een of meer transactionele objecten, dan zal je iedere keer als
je de $Object wilt hebben, naar de transactie moeten gaan om het op te halen. Dit ophalen is kostbaar
(in ieder geval een stuk kostbaarder dan een variable. En het ophalen gaat door de extra code dat nodig is,
ook de JIT in de weg zitten.
doel:
-verminderen van het aatal verzoeken dat gedaan wordt om de state op te halen.
-JIT niet in de weg zitten bij optimalisaties
Randvoorwaarden:
- als de waarde niet veranderd (finals bv)
- als de waarde wel veranderd, moet je nieuwe $Object ophalen... maar kan nog steeds geoptimaliseerd worden.
voor:
public int pop() {
Transaction t = TransactionThreadLocal.get();
if (readyToPopStack.isEmpty()) {
while (!pushedStack.isEmpty()) {
readyToPopStack.push(pushedStack.pop());
}
}
return readyToPopStack.pop();
}
1<=kosten<=(readyToPopStack + 3*pushedStack.size)*Transaction.read
na:
public int pop() {
Transaction t = TransactionThreadLocal.get();
$IntStack $readyToPopStack = ($IntStack) t.read(readyToPopStack);
if ($readyToPopStack.isEmpty()) {
$IntStack $pushedStack = ($IntStack) t.read(pushedStack);
while (!$pushedStack.isEmpty()) {
$readyToPopStack.push($pushedStack.pop());
}
}
return $readyToPopStack.pop();
}
}
1<=kosten<=2 * Transaction.read
--------------- Constant Simplification Optimization --------------
---------------- Pass $Object instead Object optimization ---------
Probleem:
Als je een methode hebt die daarin een transactioneel Object mee krijgt, zal binnen die methode het $Object
opgehaald moeten worden. Dit kan kostbaar zijn. Als de callee de $Object toch al heeft, dan is het eenvoudiger
om de $Object mee te geven.
Oplossing:
Genereer een extra methode:
voor
public static void inc(IntValue intValue){
Transaction t = TransactionThreadLocal.get();
$IntValue $intValue = ($IntValue)intValue;
$intValue.set($intValue.get());
}
public static void inc2(IntValue intValue){
inc(intValue);
inc(intValue);
}
na
public static void inc($IntValue $intValue){
$intValue.set($intValue.get());
}
public static void inc2(IntValue intValue){
$IntValue $intValue = ($IntValue)getTransaction().read(intValue);
$intValue.inc();
$intValue.inc();
}
public static void inc2($IntValue $intValue){
$intValue.inc();
$intValue.inc();
}
De caller van de inc2 functie kan nu dus kiezen uit de inc2 waar het $Object nog opgehaald moet worden,
en waar niet. Als je kijkt naar de laatste inc2, dan zie je dat hij niets duurder is dan een klassieke POJO.
Randvoorwaarden:
------------------- Reduce Return Value Transformation optimization ---------------------
Problem:
Onnodig return values omzetten is kostbaar, dus je kunt een extra methode aanbieden
voor:
public IntValue min(IntValue a, IntValue b){
}
public void foo(IntValue a, IntValue b){
IntValue result = min(a,b);
result.inc();
}
na:
public $IntValue $min(IntValue a, IntValue b){
}
public void foo(IntValue a, IntValue b){
$IntValue $result = min(a,b);
$result.inc();
}
-------------------- Readonly Transaction Optimization ? ---------
De optimalisaties zouden onafhankelijk
----------------------- kosten optimalisatie inzichtelijk maken:
het aantal keren dat er een Transaction.read gedaan moet worden.
-----------------
meerdere keren transactie ophalen binnen een methode kan vervangen worden door een enkele keer ophalen.

View file

@ -0,0 +1,35 @@
todo
- er is een probleem met atomic en constructors.
- Het toevoegen van een Atomic annotation geeft problemen met een constantpool.
- bij de Tranlocal nog een snapshot
- TranlocalSnapshot
- de debug info van de methodes uit de FastAtomicObjectMixin meenemen naar de class zelf.
- test for multiple clinit clauses
idea
done
- de automatic package moet gerenamed worden.
- Tranlocal opzetten mbv tree api
- bij de Tranlocal moet nog een committed check gedaan worden
- problemen met het toevoegen van nieuwe classes in asm structuur
- aangezien je een chain hebt, ben je de orginele kwijt... zou je die misschien mee kunnen geven?
- de nieuwe Tranlocal toevoegen aan de classloader.
- Tranlocal en privatize constructor
- bij de Tranlocal getDirtnessState

View file

@ -0,0 +1,219 @@
todo tasks
- testen wat er gebeurd bij een duplicate field.. dus als je een field toevoegd doe ook al in
de mixin zit.
- testen wat er gebeurd bij een duplicate method... dus als een method toevoegd doe ook al
in de mixin zit.
- er is een probleem bij een atomicobject zonder velden
- flashback transactions test
- de exclude functionaliteit moet getest worden.
- instrumentatie gaat fout als er velden worden uitgesloten (misschien access, misschien exclude) en
blijven dus netjes in de AtomicObject staan, maar de code die doet aanroepen op de Tranlocal.
Dit kan opgelost worden mbv een custom remapper implementatie te maken.
- stm exectutor aanpassen zodat hij op de instrumentatie werkt.
- constructors en atomic kunnen niet goed omgaan met super calls
- constructors en atomic kunnen niet goed omgaan met this calls
- de Tranlocal bij de instrumentatie moet speciale behandeling hebben voor methods zodat
ze public zijn.
- TransactionalObject annotation and AtomicObject interface
- bij de tranlocal instrumentatie, een grote hoeveelheid no-ops in de code.
- incTransactionReadonlyCount: niet gebruikt
- instead of having a locked bit, the tranlocal could have access to the transaction. Once committed,
this reference can be set to null. Can also be used for detecting if a tranlocal can in from a different
transaction.
- what happens when a throwable is thrown while executing the orelse template. if the throwable
is caught, it leaves the transaction in an inconsistent state.
- exceptions in the exception package zijn afhankelijk van de standard package
- de name 'standard' voor de default stm implementation is lame.
- the interfaces in the api package contain a lot of implementation specific stuff. A lot of that
stuff could be added using instrumentation.
- de methods of the AtomicObject should be part of the standard implementation.
- RetrySpinningWriteSetLockPolicy
- BalancedTree moet nog rotatie hebben
- wat moet er gebeuren als een transactie een load doet op uncommitted data.
+ opgelost in de code
+ opgelost in de documentatie van de load methodes
- opgelost in de code van andere methodes behalve de loadmethods van de transactie.
- documentatie
- unit tests
- FastTom.registerRetryListener en de noProgressPossibleException
- atomic en constructors werk niet goed mbt instrumentatie.. Class validate fout
-de PipelineLongTest geeft bij het debuggen een :
java.lang.ClassFormatError: Invalid length 65519 in LocalVariableTable in class file org/multiverse/integration/PipelineLongTest
Dit komt door de atomicclassfiletransformer aangezien dat de enigste instrumentatie is die er nu in zit.
- FastTomTest afmaken
- checkin op subversion
- LOAD PROBLAMTIEK
- it could happen that a readonly transaction fails because it reads a TransactionalObject that
is locked.
- privatize functie aanpassen zodat fail fast.
- it could happen that a writetransaction fails with the privatized call because it reads a
TransactionalObject that is locked.
- IntValuePerformanceTest moet naar benchy geport worden.
- CigaretteSmokersProblemSimplifiedTest
- move the benchmarks to this project
- depends on instrumentation
- SpinningWriteSetlockPolicy unit tests
todo features
- name on transaction
- retry in instrumentation needs to be added
- retry limit on atomictemplate.
- support for real serialized isolation level
- instrumentation of Transactional Objects.
- history for stale objects
- customizable contention managers
- customizable lock acquire manager.
- pessimistic locking online
- nested transactions
- SkipList
- better queue that allows better concurrency.
idea:
- a performance test comparing the 'managed ref' approach vs the full blown multiverse approach.
- a performance comparison between 'uninstrumented' code and instrumented code.
- statistics about number of loads that could get information from the transaction instead
of loading from main memory. This is also needed for optimizing bytecode.
- Commute Clojure nazoeken
- after commit event (for example for starting threads).
- could the abort and retry mechanism be implemented more efficiently? Atm the whole transaction
is aborted and the complete transaction needs to be re-done. A more efficient implemention could block
and wait until a write has happened on some field and continue with the operation, just like a classic
wait/notify.
- more efficient wait/notify: for example the balancedtree and sleeping for a specific key. Atm
all objects loaded by a transaction are a reason to wake up (cause a change happens on them). But
what if you are only interested in a specific field... this could reduce the stress on the mechanism
- logging instrumentation: instrumentation that adds logging.
- transaction level statistics
- jmx component om statistics grafisch inzichtelijk te maken
- door onderscheid te maken tussen attachednew en loaded, zou je eventueel nog optimalisaties kunnen doen:
- op nieuw objecten hoef je geen lock aan te vragen
- op nieuw objecten hoef je niet te valideren
- op nieuw objecten hoef je geen lock te releasen
- op nieuw objecten hoef je je niet druk te maken over retrylisteners
- online pessimistic locking
- Optimization for transaction usage
via DebugConstants er in laten genereren
- exceptions opnieuw aanmaken of bestaande instance hergebruiken:
- te kijken wat te doen met de exception hierarcy.. zoals moeten andere exceptions extenden van abortexception and
retryerror?
- bloomfilter
- heeft het nu om een read op een writetransactie te hebben terwijl je de $readPrivatized daar ook al hebt?
- abort silently
- retry moet gebeuren als er een write is gebeurd
- all methods of transactionalobjects should automatically have the automic tag
- ipv de cheap latch zou je ook de monitor lock van de transactie kunnen gebruiken.
Dit scheelt nog een object creatie.
- enchance the $Object structure so that it also can be used for tree (replacement for the identity hashmap)
- timeout tijd.. spaarrekening waar je iedere keer vanaf kunt boeken.
- de timeout tijds op de locks zetten
- een abortAndRetry interruptibly?
- abort en retry met timeouts?
- managed ref annotation: by setting a ref, you don't force an object to an atomic object
but a normal object using a managed ref.
done
- fields can be excluded by using the @Exclude annotation.
- dirtiness state -> dirtiness status so that is looks more like the transactionstatus.
- cyclichandling test TranlocalSingleLinkedNode en origin
- documentatie bij de stm is matig
- TL2STM is onlogisch qua naamgeving aangezien TL2 niet wordt gebruikt.
- package indeling: in de root staan zowel de interfaces als implementaties.
- bij de AtomicObject heb je een load die een immutable versie terug geeft, en een privatize voor
een mutable versie. Bij de transactie heb je een load die een mutable versie terug geeft, en een
load readonly die een immutable versie terug geeft. Dit is inconsistent.
- incTransactionPendingRetryCount: niet gebruikt
- incTransactionRetriedCount: niet gebruikt
- de naam voor tranlocal moet nog aangepast worden in de instrumentatie
- exception hierarchy still is messy
- constructors van atomicobjecten testen
---------------------------------
de writes gebeuren nadat de versie is opgehoogd, je kunt dus niet zomaar de laatste versie uitlezen

View file

@ -0,0 +1,180 @@
doel:
bepalen welke initiele transformaties (zonder optimalisaties) nodig zijn
------------------- volledig stateless classes-----------------------------------------------------------
aangezien ze geen state hebben kunnen ze geignored worden.
-------------------- objecten met alleen maar primtives zonder interfaces en super classes ---------------
voor:
class Foo{
int a;
boolean b;
void inc(){
a++;
}
}
na:
class Foo implements TransactionalObject{
Foo(){
Transaction t = TransactionThreadLocal.get();
t.attachAsNew(new $Foo());
}
void inc(){
Transaction t = TransactionThreadLocal.get();
$Foo $foo = ($Foo)t.read(this);
$foo.inc();
}
+alle methods van TransactionalObject
}
class $Foo implements $Object{
int a;
int b;
boolean committed;
long version;
void inc(){
if(committed){
throw new ReadonlyException();
}else{
a++;
}
}
...
+ methods van $Object
}
Stappen:
- Plaats TransactionalObject interface op Original en implementeer die
- Verhuis alle velden van Object naar $Object
- Copieer de methodes van Object naar $Object
- Transformeer alle methodes van Original zodat ze de call forwarden naarde $Object
- de methodes die een mutatie aanbrengen op het $Object moeten voorzien zijn van een committed check.
- ? Moet de $Object ook de interfaces/superclasses van de Original overnemen?
--------------- methodes zonder argumenten ------------------------------------
--------------- methodes met primitive argumenten -----------------------------
--------------- methodes met transactional argumenten -------------------------
--------------- methodes met runtime determined argumenten --------------------
--------------- methode met void return type ----------------------------------
--------------- methode met primtive return type ------------------------------
---------------
--------------- objecten met non stm members and non primitives ---------------
---------------- object met only final fields ---------------------------------
voor:
class IntValueConstant{
final IntValue intValue;
public IntValueConstant(int i){
intValue = new IntValue(i);
}
void inc(){
intValue.inc();
}
}
na:
class IntValueConstant{
final IntValue intValue;
public IntValueConstant(int i){
intValue = new IntValue(i);
}
}
todo: hoeft dus niets aan te gebeuren.
--------------- objecten met mutable stm members ------------------------------
voor:
class IntValueHolder{
IntValue intValue;
void set(IntValue intValue){
this.intValue = intValue;
}
IntValue get(){
return intValue;
}
}
na:
class IntValueHolder{
void set(IntValue intValue){
Transaction t = TransactionThreadLocal.get();
$IntValueHolder tranlocalThis = ($IntValueHolder)t.read(this);
tranlocalThis.set(intValue);
}
}
class $IntValueHolder implements $Object{
IntValue intValue;
void set(IntValue intValue){
this.intValue = intValue;
}
void get(){
return intValue;
}
}
---------------- objecten met runtime determined stm members -----------------
----------------- static inner objects ---------------------------------------
--------------------- non static inner objects -------------------------------
------------------- subclasses -----------------------------------------------
------------------- static methods -------------------------------------------
-------------------- missing transaction -------------------------------------
idealiter zou je willen dat zo gauw er geen transactie aanwezig is, er een wordt gemaakt en na afloop
weer wordt gecommit.

Some files were not shown because too many files have changed in this diff Show more