synchronized performance
bearophile
bearophileHUGS at lycos.com
Thu Nov 5 06:36:01 PST 2009
A synthetic benchmark for the synchronized, in D and Java:
Timings:
LDC with synchronized: 8.96
LDC without synchronized: 0.02
Java with synchronized: 0.68 (-server)
Java without synchronized: 0.27 (-server)
Defining Foo as "scope" in D produces similar timings.
// D version
version (Tango) import tango.stdc.stdio: printf;
final class Foo {
int x;
this(int x) { this.x = x; }
public synchronized int next() {
x++;
return x;
}
}
void main() {
auto f = new Foo(0);
int res;
for (int i = 0; i < 100000000; i++)
res = f.next();
printf("%d\n", res);
}
-----------------
// Java version
final class Foo {
int x;
public Foo(int x) { this.x = x; }
public synchronized int next() {
x++;
return x;
}
}
public final class Sync {
public static void main(String args[]) {
Foo f = new Foo(0);
int res = 0;
for (int i = 0; i < 100000000; i++)
res = f.next();
System.out.println(res);
}
}
Asm produced by LDC (next() is inlined):
_Dmain:
pushl %ebx
pushl %edi
pushl %esi
subl $8, %esp
movl $_D6test_d3Foo7__ClassZ, (%esp)
call _d_allocclass
movl $_D6test_d3Foo6__vtblZ, (%eax)
movl $0, 4(%eax)
movl $0, 8(%eax)
movl $100000000, %esi
movl %eax, %edi
.align 16
.LBB3_1:
movl %edi, (%esp)
call _d_monitorenter
movl 8(%edi), %ebx
incl %ebx
movl %ebx, 8(%edi)
movl %edi, (%esp)
call _d_monitorexit
decl %esi
jne .LBB3_1
movl %ebx, 4(%esp)
movl $.str1, (%esp)
call printf
xorl %eax, %eax
addl $8, %esp
popl %esi
popl %edi
popl %ebx
ret $8
This is from the disassembly of the inner loop with "scope" (compiled with LDC with link-time optimization), the code is about the same:
80495d0: mov %edi,(%esp)
80495d3: call 804d030 <_d_monitorenter>
80495d8: mov 0x10(%esp),%ebx
80495dc: inc %ebx
80495dd: mov %ebx,0x10(%esp)
80495e1: mov %edi,(%esp)
80495e4: call 804d070 <_d_monitorexit>
80495e9: inc %esi
80495ea: cmp $0x5f5e0ff,%esi
80495f0: jle 80495d0 <_Dmain+0x30>
The disassembly of _d_monitorenter and _d_monitorexit, that contain several other calls:
0804d030 <_d_monitorenter>:
804d030: push %edi
804d031: push %esi
804d032: sub $0x4,%esp
804d035: mov 0x10(%esp),%esi
804d039: mov 0x4(%esi),%eax
804d03c: test %eax,%eax
804d03e: jne 804d04b <_d_monitorenter+0x1b>
804d040: mov %esi,(%esp)
804d043: call 804e9c0 <_d_monitor_create>
804d048: mov 0x4(%esi),%eax
804d04b: mov (%eax),%edi
804d04d: test %edi,%edi
804d04f: jne 804d05f <_d_monitorenter+0x2f>
804d051: mov %esi,(%esp)
804d054: call 804e900 <_d_monitor_lock>
804d059: add $0x4,%esp
804d05c: pop %esi
804d05d: pop %edi
804d05e: ret
804d05f: mov %edi,(%esp)
804d062: call 8057620 <_d_toObject>
804d067: mov (%edi),%ecx
804d069: call *0x4(%ecx)
804d06c: jmp 804d059 <_d_monitorenter+0x29>
804d06e: xchg %ax,%ax
0804d070 <_d_monitorexit>:
804d070: push %esi
804d071: sub $0x8,%esp
804d074: mov 0x10(%esp),%eax
804d078: mov 0x4(%eax),%ecx
804d07b: mov (%ecx),%esi
804d07d: test %esi,%esi
804d07f: jne 804d08e <_d_monitorexit+0x1e>
804d081: mov %eax,(%esp)
804d084: call 804e8b0 <_d_monitor_unlock>
804d089: add $0x8,%esp
804d08c: pop %esi
804d08d: ret
804d08e: mov %esi,(%esp)
804d091: call 8057620 <_d_toObject>
804d096: mov (%esi),%ecx
804d098: call *0x8(%ecx)
804d09b: jmp 804d089 <_d_monitorexit+0x19>
804d09d: lea 0x0(%esi),%esi
Bye,
bearophile
More information about the Digitalmars-d
mailing list