Permalink
Browse files

fiber optimization

  • Loading branch information...
1 parent 1794372 commit a55449ee5fe9d4fad1b7de30520260d8785a2e8b @krestenkrab krestenkrab committed Dec 3, 2009
View
10 pom.xml
@@ -23,6 +23,14 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
@@ -52,4 +60,4 @@
<version>3.2</version>
</dependency>
</dependencies>
-</project>
+</project>
View
90 src/kilim/java/kilim/Fiber.java
@@ -42,7 +42,9 @@
* One State object for each activation frame in the call hierarchy.
*/
private State[] stateStack = new State[10];
-
+ private Object[] selfStack = new Object[10];
+ private int[] pcStack = new int[10];
+
/*
* Index into stateStack and equal to depth of call hierarchy - 1
*/
@@ -60,7 +62,9 @@
/*
* Special marker state used by pause
*/
+ private static final int PAUSE_STATE_PC = 1;
private static final State PAUSE_STATE = new State();
+ private static final State EMPTY_STATE = new State();
/*
* Status indicators returned by down()
@@ -85,10 +89,6 @@
*/
private static final int PAUSING__HAS_STATE = 3;
- static {
- PAUSE_STATE.pc = 1;
- }
-
public Fiber(Task t) {
task = t;
}
@@ -152,33 +152,14 @@ public int up() {
return NOT_PAUSING__NO_STATE;
} else {
stack[d] = null; // clean up
- pc = cs.pc;
+ pc = pcStack[d];
// if (debug) System.out.println("\nup(not pausing)" + this);;
// if (debug) ds();
- cs.releaseTo(this);
return NOT_PAUSING__HAS_STATE;
}
}
}
- private static final int STATE_POOL_SIZE = 10;
- int pool_count = 0;
- State[] pool = new State[STATE_POOL_SIZE];
-
- public final State allocState()
- {
- if (pool_count==0) return new State();
- return pool[--pool_count];
- }
-
- final void release(State s) {
- if (pool_count != STATE_POOL_SIZE) {
- pool[pool_count++] = s;
- s.self = null;
- }
- }
-
-
public final Fiber begin() {
return down();
}
@@ -219,7 +200,7 @@ public Fiber down() {
} else {
State s = stateStack[d];
curState = s;
- pc = (s == null) ? 0 : s.pc;
+ pc = (s == null) ? 0 : pcStack[d];
}
// if (debug) System.out.println("down:\n" + this);
// if (debug) ds();
@@ -262,16 +243,17 @@ static void ds() {
*/
public int upEx() {
// compute new iStack.
- int is = task.getStackDepth() - 2; // remove upEx and convert to 0-based index.
+ final int is = task.getStackDepth() - 2; // remove upEx and convert to 0-based index.
State cs = stateStack[is];
for (int i = iStack; i >= is; i--) {
stateStack[i] = null; // release state
+ selfStack[i] = null; // release state
}
iStack = is;
curState = cs;
- return (cs == null) ? 0 : cs.pc;
+ return (cs == null) ? 0 : pcStack[is];
}
/**
@@ -282,25 +264,60 @@ public int upEx() {
public Object getCallee() {
assert stateStack[iStack] != PAUSE_STATE : "No callee: this state is the pause state";
assert stateStack[iStack] != null : "Callee is null";
- return stateStack[iStack + 1].self;
+ return selfStack[iStack + 1];
}
- private State[] ensureSize(int newsize) {
+ private void ensureSize(int newsize) {
// System.out.println("ENSURE SIZE = " + newsize);
+ int len = stateStack.length;
+
State[] newStack = new State[newsize];
- System.arraycopy(stateStack, 0, newStack, 0, stateStack.length);
+ System.arraycopy(stateStack, 0, newStack, 0, len);
stateStack = newStack;
- return newStack;
- }
+
+ Object[] newSelfStack = new Object[newsize];
+ System.arraycopy(selfStack, 0, newSelfStack, 0, len);
+ selfStack = newSelfStack;
+
+ int[] newPCStack = new int[newsize];
+ System.arraycopy(pcStack, 0, newPCStack, 0, len);
+ pcStack = newPCStack;
+}
/**
* Called by the generated code before pausing and unwinding its stack
* frame.
*
* @param state
*/
- public void setState(State state) {
+ public void setState(State state, Object self, int pc) {
stateStack[iStack] = state;
+ selfStack[iStack] = self;
+ pcStack[iStack] = pc;
+ isPausing = true;
+// System.out.println("setState[" + + iStack + "] = " + this);
+ }
+
+ public void setState(State state, int pc) {
+ stateStack[iStack] = state;
+ selfStack[iStack] = null;
+ pcStack[iStack] = pc;
+ isPausing = true;
+// System.out.println("setState[" + + iStack + "] = " + this);
+ }
+
+ public void setState(Object self, int pc) {
+ stateStack[iStack] = EMPTY_STATE;
+ selfStack[iStack] = self;
+ pcStack[iStack] = pc;
+ isPausing = true;
+// System.out.println("setState[" + + iStack + "] = " + this);
+ }
+
+ public void setState(int pc) {
+ stateStack[iStack] = EMPTY_STATE;
+ selfStack[iStack] = null;
+ pcStack[iStack] = pc;
isPausing = true;
// System.out.println("setState[" + + iStack + "] = " + this);
}
@@ -311,9 +328,10 @@ void togglePause() {
// upto date.
if (curState == null) {
- setState(PAUSE_STATE);
+ setState(PAUSE_STATE, PAUSE_STATE_PC);
} else {
- assert curState == PAUSE_STATE : "togglePause: Expected PAUSE_STATE, instead got: iStack == " + iStack + ", state = " + curState;
+ assert curState == PAUSE_STATE :
+ "togglePause: Expected PAUSE_STATE, instead got: iStack == " + iStack + ", state = " + curState;
stateStack[iStack] = null;
isPausing = false;
}
View
11 src/kilim/java/kilim/State.java
@@ -25,13 +25,6 @@
*/
public class State {
- public int pc;
- public Object self;
-
- /**
- * @param fiber
- */
- void releaseTo(Fiber fiber) {
- fiber.release(this);
- }
+ //public int pc;
+ //public Object self;
}
View
70 src/kilim/java/kilim/analysis/CallWeaver.java
@@ -516,32 +516,41 @@ private void genSave(MethodVisitor mv, Label saveLabel) {
* the method weaver's list. This allows us to do a switch in the
* method's entry.
*/
- if (stateClassName.equals(STATE_CLASS)) {
+ boolean is_simple_state = stateClassName.equals(STATE_CLASS);
+
+ if (is_simple_state) {
+
loadVar(mv, TOBJECT, methodWeaver.getFiberVar());
- mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "allocState", "()" + D_STATE);
+
+ if (!bb.flow.isStatic()) {
+ mv.visitInsn(ALOAD_0); // for state.self == this
+ }
+
+ int pc = methodWeaver.getPC(this);
+ if (pc < 6) {
+ mv.visitInsn(ICONST_0 + pc);
+ } else {
+ mv.visitIntInsn(BIPUSH, pc);
+ }
+
+ if (!bb.flow.isStatic()) {
+ methodWeaver.ensureMaxStack(3);
+ mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "setState", "(Ljava/lang/Object;I)V");
+ } else {
+ methodWeaver.ensureMaxStack(2);
+ mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "setState", "(I)V");
+ }
+
+
} else {
mv.visitTypeInsn(NEW, stateClassName);
mv.visitInsn(DUP); //
// call constructor
mv.visitMethodInsn(INVOKESPECIAL, stateClassName, "<init>", "()V");
- }
+
// save state in register
int stateVar = allocVar(1);
storeVar(mv, TOBJECT, stateVar);
- // state.self = this if the current executing method isn't static
- if (!bb.flow.isStatic()) {
- loadVar(mv, TOBJECT, stateVar);
- mv.visitInsn(ALOAD_0); // for state.self == this
- mv.visitFieldInsn(PUTFIELD, STATE_CLASS, "self", D_OBJECT);
- }
- int pc = methodWeaver.getPC(this);
- loadVar(mv, TOBJECT, stateVar); // state.pc
- if (pc < 6) {
- mv.visitInsn(ICONST_0 + pc);
- } else {
- mv.visitIntInsn(BIPUSH, pc);
- }
- mv.visitFieldInsn(PUTFIELD, STATE_CLASS, "pc", D_INT);
// First save bottom stack into state
int i = getNumBottom() - 1;
@@ -585,9 +594,32 @@ private void genSave(MethodVisitor mv, Label saveLabel) {
// Fiber.setState(state);
loadVar(mv, TOBJECT, methodWeaver.getFiberVar());
loadVar(mv, TOBJECT, stateVar);
- mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "setState", "("
- + D_STATE + ")V");
+
+ if (!bb.flow.isStatic()) {
+ mv.visitInsn(ALOAD_0); // for state.self == this
+ }
+
+ int pc = methodWeaver.getPC(this);
+ if (pc < 6) {
+ mv.visitInsn(ICONST_0 + pc);
+ } else {
+ mv.visitIntInsn(BIPUSH, pc);
+ }
+
+ if (!bb.flow.isStatic()) {
+ methodWeaver.ensureMaxStack(4);
+ mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "setState", "("
+ + D_STATE + "Ljava/lang/Object;I)V");
+ } else {
+ methodWeaver.ensureMaxStack(3);
+ mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "setState", "("
+ + D_STATE + "I)V");
+ }
+
releaseVar(stateVar, 1);
+ }
+
+
// Figure out the return type of the calling method and issue the
// appropriate xRETURN instruction
retType = TypeDesc.getReturnTypeDesc(bb.flow.desc);
View
6 src/kilim/java/kilim/analysis/ClassWeaver.java
@@ -190,12 +190,6 @@ String createStateClass(ValInfoList valInfoList) {
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_1, ACC_PUBLIC | ACC_FINAL, className, null, "kilim/State", null);
- MethodVisitor mv = cw.visitMethod(0, "releaseTo", "(Lkilim/Fiber;)V" , null, null);
- mv.visitCode();
- mv.visitInsn(RETURN);
- mv.visitMaxs(1, 2);
- mv.visitEnd();
-
// Create default constructor
// <init>() {
// super(); // call java/lang/Object.<init>()
View
69 src/main/erl/fib.erl
@@ -0,0 +1,69 @@
+-module(fib).
+-export([fibo/1, fibo2/1, fibo3/1, print_nfibos/2, main/0, runLength/2, main2/0]).
+
+%% print fibo arg. and result, with function as parameter
+
+print_nfibos( N, FiboFunc) -> printfibos( N, FiboFunc, 0).
+
+printfibos( 0, FiboFunc, N) -> %% last recursion
+ Res = FiboFunc(N),
+ io:format("~w ~w~n", [N, Res]) ;
+
+printfibos( Iter, FiboFunc, N) when Iter > 0 ->
+ Res = FiboFunc(N),
+ io:format("~w ~w~n", [N, Res]),
+ printfibos( Iter -1, FiboFunc, N +1).
+
+
+
+fibo(0) -> 0 ;
+fibo(1) -> 1 ;
+fibo(N) when N > 0 -> fibo(N-1) + fibo(N-2) .
+
+
+fibo2_tr( 0, Result, _Next) -> Result ; %% last recursion output
+
+fibo2_tr( Iter, Result, Next) when Iter > 0 -> fibo2_tr( Iter -1, Next, Result + Next) .
+
+fibo2( N) -> fibo2_tr( N, 0, 1) .
+
+
+fibo3(N) ->
+ {Fib, _} = fibo3(N, {1, 1}, {0, 1}),
+ Fib.
+
+fibo3(0, _, Pair) -> Pair;
+fibo3(N, {Fib1, Fib2}, Pair) when N rem 2 == 0 ->
+ SquareFib1 = Fib1*Fib1,
+ fibo3(N div 2, {2*Fib1*Fib2 - SquareFib1, SquareFib1 + Fib2*Fib2}, Pair);
+fibo3(N, {FibA1, FibA2}=Pair, {FibB1, FibB2}) ->
+ fibo3(N-1, Pair, {FibA1*FibB2 + FibB1*(FibA2 - FibA1), FibA1*FibB1 + FibA2*FibB2}).
+
+
+time(F,N) ->
+ {Time,_Res} = timer:tc(fib,F,[N]),
+ io:format("~w,~w,~w~n", [F,N,Time]).
+
+tlength(L) -> tlength(L,0).
+tlength([_|T],Acc) -> tlength(T,Acc+1);
+tlength([],Acc) -> Acc.
+
+makeList(N) when N==0 -> [];
+makeList(N) -> [N,makeList(N-1)].
+
+runLength(_,N) when N==0 -> done;
+runLength(L,N) -> tlength(L), runLength(L,N-1).
+
+main() ->
+ List = makeList(2000),
+ io:format("time=~w~n", [timer:tc(fib,runLength,[List,1000000])]).
+
+main2() ->
+ time(fibo3,10),
+ time(fibo3,100),
+ time(fibo3,1000),
+ time(fibo3,10000),
+ time(fibo3,100000),
+ time(fibo3,1000000).
+
+
View
2 src/main/java/erjang/ERT.java
@@ -348,7 +348,7 @@ public static EObject apply(EProc proc, EObject mod, EObject fun) throws Pausabl
if (m==null||f==null) throw ERT.badarg(mod, fun);
EFun efun = EModule.resolve(new FunID(m,f,0));
- return efun.invoke(proc, new EObject[] { });
+ return efun.invoke(proc, new EObject[0]);
}
public static EObject apply$last(EProc proc, EObject arg1, EObject mod, EObject fun)
View
1 src/main/java/erjang/Erj.java
@@ -62,6 +62,7 @@ public static void main(String[] args) throws ClassNotFoundException, MalformedU
}
EModule.load_module(EAtom.intern("io"), new File("target/classes").toURL());
+ EModule.load_module(EAtom.intern("timer"), new File("target/classes").toURL());
load(new File("src/main/erl/" + m + ".classes"), m);

0 comments on commit a55449e

Please sign in to comment.