atomics

BogDan bog_dan_ro at yahoo.com
Fri Jul 8 15:33:47 CEST 2011


Hello Folks,

I've made a small application to test current available atomic implementations on android.
This are the results on a HTC sensation device:


Test 1
===============================
USING SMP safe ASM instructions
--------------------------------------------------------------------
Executing test_atomic_cmpxchg_ASM took 14714 
Executing test_atomic_cmpxchg_GCC took 15685 
Executing test_atomic_cmpxchg_Android took 8874 
Executing test_atomic_inc_ASM took 14310 
Executing test_atomic_inc_GCC took 16190 
Executing test_atomic_inc_Android took 8351
===============================
Test 2
===============================
USING SMP unsafe ASM instructions 
--------------------------------------------------------------------
Executing test_atomic_cmpxchg_ASM took 6904 
Executing test_atomic_cmpxchg_GCC took 15814 
Executing test_atomic_cmpxchg_Android took 8864 
Executing test_atomic_inc_ASM took 6404 
Executing test_atomic_inc_GCC took 16048
Executing test_atomic_inc_Android took 8198 
===============================



And this is the code:

#include<QDebug>
#include<QDateTime>
#include<sys/atomics.h>
staticconstintLOOPS=100000000;
#defineSMP_SAFE
#ifdefSMP_SAFE
#definesmp_mb__asm____volatile__("dmb":::"memory")
#else
#definesmp_mb
#endif
intatomic_cmpxchg(int&_q_value,intexpectedValue,intnewValue)
{
registerintresult;
smp_mb;
asmvolatile("0:\n"
"ldrex%[result],[%[_q_value]]\n"
"eors%[result],%[result],%[expectedValue]\n"
"itteq\n"
"strexeq%[result],%[newValue],[%[_q_value]]\n"
"teqeq%[result],#1\n"
"beq0b\n"
:[result]"=&r"(result),
"+m"(_q_value)
:[expectedValue]"r"(expectedValue),
[newValue]"r"(newValue),
[_q_value]"r"(&_q_value)
:"cc");
smp_mb;
returnresult==0;
}
voidtest_atomic_cmpxchg_ASM()
{
inttest=0;
for(inti=0;i<LOOPS;i++)
{
atomic_cmpxchg(test,test,test+1);
}
qDebug()<<test;
}
voidtest_atomic_cmpxchg_GCC()
{
inttest=0;
for(inti=0;i<LOOPS;i++)
{
__sync_bool_compare_and_swap(&test,test,test+1);
}
qDebug()<<test;
}
voidtest_atomic_cmpxchg_Android()
{
inttest=0;
for(inti=0;i<LOOPS;i++)
{
__atomic_cmpxchg(test,test+1,&test);
}
qDebug()<<test;
}
intatomic_inc(int&_q_value,intvalueToAdd)
{
registerintoriginalValue;
registerintnewValue;
registerintresult;
smp_mb;
asmvolatile("0:\n"
"ldrex%[originalValue],[%[_q_value]]\n"
"add%[newValue],%[originalValue],%[valueToAdd]\n"
"strex%[result],%[newValue],[%[_q_value]]\n"
"teq%[result],#0\n"
"bne0b\n"
:[originalValue]"=&r"(originalValue),
[newValue]"=&r"(newValue),
[result]"=&r"(result),
"+m"(_q_value)
:[valueToAdd]"r"(valueToAdd),
[_q_value]"r"(&_q_value)
:"cc");
smp_mb;
returnoriginalValue;
}
voidtest_atomic_inc_ASM()
{
inttest=0;
intlast=0;
for(inti=0;i<LOOPS;i++)
{
last=atomic_inc(test,1);
}
qDebug()<<test<<last;
}
voidtest_atomic_inc_GCC()
{
inttest=0;
intlast=0;
for(inti=0;i<LOOPS;i++)
{
last=__sync_fetch_and_add(&test,1);
}
qDebug()<<test<<last;
}
voidtest_atomic_inc_Android()
{
inttest=0;
intlast=0;
for(inti=0;i<LOOPS;i++)
{
last=__atomic_inc(&test);
}
qDebug()<<test<<last;
}
voidtestAtomics()
{
#ifdefSMP_SAFE
qDebug()<<"USINGSMPsafeASMinstructions";
#else
qDebug()<<"USINGSMPunsafeASMinstructions";
#endif
QDateTimestart=QDateTime::currentDateTimeUtc();
test_atomic_cmpxchg_ASM();
qDebug()<<"Executingtest_atomic_cmpxchg_ASMtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
start=QDateTime::currentDateTimeUtc();
test_atomic_cmpxchg_GCC();
qDebug()<<"Executingtest_atomic_cmpxchg_GCCtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
start=QDateTime::currentDateTimeUtc();
test_atomic_cmpxchg_Android();
qDebug()<<"Executingtest_atomic_cmpxchg_Androidtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
start=QDateTime::currentDateTimeUtc();
test_atomic_inc_ASM();
qDebug()<<"Executingtest_atomic_inc_ASMtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
start=QDateTime::currentDateTimeUtc();
test_atomic_inc_GCC();
qDebug()<<"Executingtest_atomic_inc_GCCtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
start=QDateTime::currentDateTimeUtc();
test_atomic_inc_Android();
qDebug()<<"Executingtest_atomic_inc_Androidtook"<<start.msecsTo(QDateTime::currentDateTimeUtc());
}


Please try this code on a different devices and post the results here.

Thanks,
BogDan.


More information about the Necessitas-devel mailing list