Pokazywanie postów oznaczonych etykietą real-time. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą real-time. Pokaż wszystkie posty

piątek, kwietnia 21, 2017

Messaging of AliExpress

The biggest world global eCommerce - AliExpress has its own messaging and its source code looks interesting especially with claims "Throughout the period, 99.996% of the delay fell within 10ms, very few due to GC caused by the pause in 50ms or less, for the read and write ratio is almost balanced distributed message engine, the results are all exciting." which are about Java software.
With first look following can be spotted: heavy usage of java.util.concurrent, volatile keyword, ByteBuffers and very limited usage of synchronized blocks. File storage uses plain RandomAccessFile with OS-mapped ByteBuffers where everything read and written is with computed offsets. Flushing data to disk is performed in file groups which is very wise due to mechanical sympathy with underlying disks (think about hardware I/O queues and servicing according to given offsets). Memory storage uses direct ByteBuffers not affected by GC and also locked into physical memory with POSIX mlock call. Very smart! I was exploiting the last feature while writing near RealTime software for T-Mobile emergency number. It really helps to achieve low latency without outliers.





wtorek, stycznia 27, 2015

JMS datastore replication: performance with enterprise server

source: sync-msgs.db 5GB, GFS2
target: EXT4

serial: WALL TIME: 121sec 133msec
sendfile: WALL TIME: 113sec 264msec
default: WALL TIME: 64sec 7msec
mmap: WALL TIME: 142sec 57msec
aio: WALL TIME: 8sec 791msec

piątek, listopada 23, 2012

Z książki 'Modele i zastosowania systemów czasu rzeczywistego'








czwartek, marca 31, 2011

Prevent JVM from swapping

import com.sun.jna.Native;

public final class LIBC {
public static final int MCL_CURRENT = 1;
public static final int MCL_FUTURE = 2;

static {
Native.register("c");
}

public static native int mlockall(int flags);
public static native int munlockall();
private LIBC() {}
}
LIBC.mlockall(LIBC.MCL_CURRENT | LIBC.MCL_FUTURE);

On Solaris box you can do: -XX:+UseISM

poniedziałek, lipca 05, 2010

SLA RealTime (QNX x86)

W najnowszym QNX-ie 6.5.0 nie ma Javy (w poprzednich wersjach bywał Aonix albo IBM), WebServer więc jest w Pythonie.


Niby wszystko ładnie, gdyby nie te outliery, które jak na system czasu rzeczywistego są spore.


Czyżby w QNX-ie nie wyrabiał się stos TCP/IP wzięty z NetBSD?



Top jednak wskazuje, że jest to zagłodzenie.


sobota, lipca 03, 2010

SLA Real-Time (OpenSolaris x86)


Zdecydowanie gorzej niż w Linuksie.



Java RT na OpenSolarisie wypada fatalnie.

SLA Real-Time (Linux x86)

Napiszmy sobie prosty i szybki serwerowy kod Javy, który powinien wyrabiać się po stronie klienta w milisekundach (w idealnych warunkach czas działania zależy od czasu stosu TCP/IP) - serwer WWW zwracający aktualną datę.


Do tego mały zły programik w C zużywający sporo cykli procesora tudzież alokujący sporo pamięci (system operacyjny przez niego będzie używał swapa)



Mamy zasymulowany obciążony serwer aplikacyjny. Programy napisane w Javie i C działają na kontach różnych użytkowników.

Na wykresie widzimy system ze zwykłą Javą 6.0 od Sun-a. Konfiguracja out-of-box. Na osi pionowej czas odpowiedzi serwera JEE w milisekundach.


Wprowadźmy teraz limity (/etc/security/limits.conf):

user hard data 200000
user hard memlock 200000
user hard cpu 50

Jest lepiej.


A to Java RT. Pamięć używana przez maszynę wirtualną jest zablokowana za pomocą funkcji mlockall() i nie może być przeniesiona do swapa.


W rezultacie mały zły program w C jest zabity przez OOM-killera.



Spójrzmy jeszcze na JRockit-a RT 4.0 (RT oznacza deterministyczny garbage collector). Prawie idealnie. Gdyby poprzez bibliotekę w C i JNI zawołać mlockall, mielibyśmy wyniki spełniające SLA RT.


WebSphere Real-Time (IBM J9 w/ Metronome GC):


piątek, września 11, 2009

Prstat

27109 adinstan  469M  323M cpu1    30    0 209:37:17  35% bwengine/64
27109 adinstan 469M 323M cpu17 20 0 209:37:45 35% bwengine/64
27109 adinstan 469M 323M cpu16 20 0 209:38:14 35% bwengine/64
27109 adinstan 469M 323M cpu17 20 0 209:38:56 35% bwengine/64
27109 adinstan 469M 323M cpu18 20 0 209:39:10 35% bwengine/64
27109 adinstan 469M 323M cpu0 10 0 209:39:24 35% bwengine/64
27109 adinstan 469M 323M cpu2 10 0 209:39:38 35% bwengine/64
27109 adinstan 469M 323M cpu19 10 0 209:40:07 35% bwengine/64
Proces skacze po procesorach. Można go dowiązać narzędziami psrset+pbind, co powinno zmniejszyć opóźnienia (ważna rzecz dla np. aplikacji RT).

sobota, marca 28, 2009

StringMaker

public class StringMaker {
private ArrayList<string> strings = new ArrayList<string>();

public StringMaker append(Object p) {
strings.add(String.valueOf(p));
return this;
}

public String toString() {
int cnt=0, p=0, l=0;
for (String s : strings) {
cnt +=s.length();
}
char[] value = new char[cnt];
for (String s : strings) {
l = s.length();
s.getChars(0, l, value, p);
p+=l;
}
return new String(value);
}
}

public class Test1 {

private final static String S = "private ArrayList<String> strings = new ArrayList<String>()";

public long[] test1() {
Random r = new Random(System.currentTimeMillis());
StringMaker sm = new StringMaker();
long t1 = System.currentTimeMillis();
for (int i=0; i < 100000; i++) {
sm.append(S.substring(r.nextInt(40)));
}
String result = sm.toString();
long t2 = System.currentTimeMillis();
return new long[] { t2-t1, result.length() };
}

// test2 - to samo na StringBufferze
// test3 - to samo na StringBuilderze
// test4 - to samo na StringBufferze(4000000)
}

BEA JRockit(R) (build R27.6.0-50_o-100423-1.6.0_05-20080626-2104-linux-ia32, compiled mode):
n=100 test1: 50ms, 3950201 chars
n=100 test2: 77ms, 3949690 chars
n=100 test3: 77ms, 3950259 chars
n=100 test4: 41ms, 3950640 chars

Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing):
n=100 test1: 92ms, 3951062 chars
n=100 test2: 118ms, 3949873 chars
n=100 test3: 118ms, 3950118 chars
n=100 test4: 36ms, 3950035 chars

IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260-20090215_29883 (JIT enabled, AOT enabled):
n=100 test1: 64ms, 3949910 chars
n=100 test2: 70ms, 3950291 chars
n=100 test3: 70ms, 3950410 chars
n=100 test4: 31ms, 3949690 chars

niedziela, lipca 13, 2008

Poprawki dla 2.6.25.10-rt7

Siadłem nad tym kernelem i doprowadziłem go do stanu używalności na moim laptopie:

libata: fix locking for kmap_atomic

pm_qos_params: change spinlock to rwlock

no i oczywiście żeby się kompilowało w kernel/sched.c trzeba dodać:

static inline u64 global_rt_runtime()
{
if (sysctl_sched_rt_period < 0)
return RUNTIME_INF;

return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC;
}
Tak przy okazji - mocny motyw:

niedziela, stycznia 20, 2008

glibc_malloc vs alloca => 166197 / 1536 = ~100


localhost systest_modules # ./malloc
Ustawianie maski procesorow na 1

-- SYSTEM INFO -------------------

localhost: Linux 2.6.24-rc7 #6 SMP PREEMPT Mon Jan 14 16:50:37 CET 2008

Ustawianie priorytetu dla SCHED_OTHER na 0 (zwykly proces) dla 29488
*** TIMED: Instrukcja: 'tab[++i] = malloc_sbrk(100);'
*** TIMED: 0sec 9357nsec +- 1nsec
Addr: 804c000

*** TIMED: Instrukcja: 'tab[++i] = malloc_mmap(100);'
*** TIMED: 0sec 8449nsec +- 1nsec
Addr: b7f0e000

*** TIMED: Instrukcja: 'tab[++i] = malloc_stos(100);'
*** TIMED: 0sec 1536nsec +- 1nsec
Addr: bf806550

*** TIMED: Instrukcja: 'tab[++i] = malloc_libc(100);'
*** TIMED: 0sec 166197nsec +- 1nsec
Addr: 804c070

Ustawianie priorytetu dla SHED_FIFO na 99 (zakres 1-99) dla 29488
*** TIMED: Instrukcja: 'tab[++i] = malloc_sbrk(100);'
*** TIMED: 0sec 5446nsec +- 1nsec
Addr: 806d000

*** TIMED: Instrukcja: 'tab[++i] = malloc_mmap(100);'
*** TIMED: 0sec 6495nsec +- 1nsec
Addr: b7f0d000

*** TIMED: Instrukcja: 'tab[++i] = malloc_stos(100);'
*** TIMED: 0sec 1396nsec +- 1nsec
Addr: bf806550

*** TIMED: Instrukcja: 'tab[++i] = malloc_libc(100);'
*** TIMED: 0sec 1816nsec +- 1nsec
Addr: 804c070

A kod wyglądał tak:


#include "framework.h"
#include

inline void* malloc_sbrk(int size) {
/* Poszerzenie przestrzeni adresowej programu */
void *addr = sbrk(size);
if (addr == (void*)-1)
addr = NULL;
return addr;
}

inline void* malloc_mmap(int size) {
/* Alokacja pamieci za pomoca mmap */
void *addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (addr == (void*)-1)
addr = NULL;
return addr;
}

inline void* malloc_stos(int size) {
/* Alokacja pamieci na stosie */
return alloca(size);
}

inline void* malloc_libc(int size) {
return malloc(size);
}

void test_malloc(int rt) {
int i = 0;
void* tab[10];

RT_ON(rt);
#define CHECK_OK() do { \
printf("Addr: %x\n\n",(unsigned int)tab[i]); \
if (tab[i] == NULL) SHOW_ERR(); \
} while(0);


TIMED(
tab[++i] = malloc_sbrk(100);
);
CHECK_OK();

TIMED(
tab[++i] = malloc_mmap(100);
);
CHECK_OK();

TIMED(
tab[++i] = malloc_stos(100);
);
CHECK_OK();

TIMED(
tab[++i] = malloc_libc(100);
);
CHECK_OK();

free(tab[i]);
}

int main(int argc, char **argv) {
one_cpu();
uname_info();
test_malloc(0);
test_malloc(1);
return 0;
}

sobota, stycznia 19, 2008

Systest 20080119

Poprawiłem wreszcie systest, żeby dawał sensowne rezultaty na systemach z więcej niż jednym procesorem. Jest to zestaw programów wykorzystujących API POSIX 1.b mierzący np. czas przełączania sie dwóch procesów
używających tego samego semafora.

Z tej samej beczki: Intel wypuścił narzędzie do badania opóźnień w systemie - http://www.latencytop.org. Nazwa nawiązuje do powertopa mierzącego przez jak długi czas procesor znajduje się w danym stanie snu (C1, C2, C3...) i co go budzi. U mnie procesor przeważnie jest budzony przez ndiswrappera. LatencyTOP wymaga linuksa 2.6.24-rc7 (na razie są patche tylko na to jądro).

Z podobnej beczki: Jak ktoś ogląda commity od 2.6.24 rc, to widać, że ludzie używają inftrastruktury RT, którą do jądra wrzucił Ingo Molnar, a pozwala ona odnaleźć błędy, które siedziały w kernelu latami. Tak więc przy okazji robienia jądra realtime zyskują wszyscy.

sobota, grudnia 01, 2007

Dorwałem ostatnio JamaicaVM od firmy Aicas - JVM czasu rzeczywistego. Ma to jedną dużą binarkę z wszystkimi systemowymi rzeczami wkompilowanymi statycznie, binarka jest stripped także w nm nie można nic zobaczyc. Linia polecen Jamajki jest niekompatybilna ze zwykłą Javą - nie można odpalić Eclipse'a (jakich przerzutek używa Eclipse można zobabaczyć w eclipse.ini). Co ciekawe Jamaica potrafi kod Javy skompilować do statycznej binarki. Fajne. Można tego używać pod Eclipsem - producent dostarcza stosowny plugin pozwalający w IDE wybrać JRE (Jak powszechnie wiadomo Eclipse nie potrzebuje JDK i javac, bo ma własny kompilator ECJ).

A poza tym to trochę się boję Pawlaka jako ministra od gospodarki...