Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

benchmarkinfo.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** BenchmarkInfo
00003 **
00004 ** A benchmark widget for Qt/Embedded
00005 **
00006 ** Copyright (C) 2004 Michael Lauer <mickey@vanille.de>
00007 ** Inspired by ZBench (C) 2002 Satoshi <af230533@im07.alpha-net.ne.jp>
00008 **
00009 ** This file may be distributed and/or modified under the terms of the
00010 ** GNU General Public License version 2 as published by the Free Software
00011 ** Foundation and appearing in the file LICENSE.GPL included in the
00012 ** packaging of this file.
00013 **
00014 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00015 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00016 **
00017 **********************************************************************/
00018 
00019 #include "benchmarkinfo.h"
00020 
00021 /* OPIE */
00022 #include <opie2/odebug.h>
00023 #include <opie2/ostorageinfo.h>
00024 #include <opie2/olistview.h>
00025 #include <opie2/oresource.h>
00026 #include <qpe/qpeapplication.h>
00027 #include <qpe/qcopenvelope_qws.h>
00028 #include <qpe/qpedecoration_qws.h>
00029 #include <qpe/config.h>
00030 using namespace Opie::Core;
00031 using namespace Opie::Ui;
00032 
00033 /* QT */
00034 #include <qclipboard.h>
00035 #include <qcolor.h>
00036 #include <qcombobox.h>
00037 #include <qdirectpainter_qws.h>
00038 #include <qfile.h>
00039 #include <qtextstream.h>
00040 #include <qfiledialog.h>
00041 #include <qlabel.h>
00042 #include <qlayout.h>
00043 #include <qpainter.h>
00044 #include <qpushbutton.h>
00045 #include <qtimer.h>
00046 #include <qwhatsthis.h>
00047 
00048 /* STD */
00049 #include <time.h>
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <math.h>
00053 #if (defined (__GNUC__) && (__GNUC__ < 3)) || defined(__UCLIBC__)
00054 #define round qRound
00055 #endif
00056 
00057 extern "C"
00058 {
00059     void BenchFFT( void );
00060     double dhry_main( int );
00061 }
00062 
00063 #define DHRYSTONE_RUNS   20000000
00064 #define TEST_DURATION    3
00065 
00066 //===========================================================================
00067 
00068 class BenchmarkPaintWidget : public QWidget
00069 {
00070   public:
00071     BenchmarkPaintWidget() : QWidget( 0, "Benchmark Paint Widget", WStyle_Customize|WStyle_StaysOnTop|WPaintUnclipped|WPaintClever )
00072     {
00073         resize( QApplication::desktop()->size() );
00074         show();
00075         p.begin( this );
00076     };
00077 
00078     ~BenchmarkPaintWidget()
00079     {
00080         p.end();
00081         hide();
00082     };
00083 
00084     QPainter p;
00085 };
00086 
00087 //===========================================================================
00088 
00089 BenchmarkInfo::BenchmarkInfo( QWidget *parent, const char *name, int wFlags )
00090         : QWidget( parent, name, wFlags )
00091 {
00092 
00093     setMinimumSize( 200, 150 );
00094 
00095     QVBoxLayout* vb = new QVBoxLayout( this );
00096     vb->setSpacing( 4 );
00097     vb->setMargin( 4 );
00098 
00099     tests = new OListView( this );
00100     QWhatsThis::add( tests->viewport(), tr( "This area shows the available tests, the results for which the tests "
00101                                 "have been performed, and comparison values for one selected device. "
00102                                 "Use the checkboxes to define which tests you want to perform." ) );
00103     tests->setMargin( 0 );
00104     tests->addColumn( tr( "Tests" ) );
00105     tests->addColumn( tr( "Results" ) );
00106     tests->addColumn( tr( "Comparison" ) );
00107     tests->setShowSortIndicator( true );
00108 
00109     test_alu = new OCheckListItem( tests, tr( "1. Integer Arithmetic  " ), OCheckListItem::CheckBox );
00110     test_fpu = new OCheckListItem( tests, tr( "2. Floating Point Unit  " ), OCheckListItem::CheckBox );
00111     test_txt = new OCheckListItem( tests, tr( "3. Text Rendering  " ), OCheckListItem::CheckBox );
00112     test_gfx = new OCheckListItem( tests, tr( "4. Gfx Rendering  " ), OCheckListItem::CheckBox );
00113     test_ram = new OCheckListItem( tests, tr( "5. RAM Performance  " ), OCheckListItem::CheckBox );
00114 #ifndef QT_QWS_RAMSES
00115     test_sd = new OCheckListItem( tests, tr( "6. SD Card Performance  " ), OCheckListItem::CheckBox );
00116     test_cf = new OCheckListItem( tests, tr( "7. CF Card Performance  " ), OCheckListItem::CheckBox );
00117 #endif
00118     test_alu->setText( 1, "n/a" );
00119     test_fpu->setText( 1, "n/a" );
00120     test_txt->setText( 1, "n/a" );
00121     test_gfx->setText( 1, "n/a" );
00122     test_ram->setText( 1, "n/a" );
00123 #ifndef QT_QWS_RAMSES
00124     test_sd->setText( 1, "n/a" );
00125     test_cf->setText( 1, "n/a" );
00126 #endif
00127     test_alu->setText( 2, "n/a" );
00128     test_fpu->setText( 2, "n/a" );
00129     test_txt->setText( 2, "n/a" );
00130     test_gfx->setText( 2, "n/a" );
00131     test_ram->setText( 2, "n/a" );
00132 #ifndef QT_QWS_RAMSES
00133     test_sd->setText( 2, "n/a" );
00134     test_cf->setText( 2, "n/a" );
00135 #endif
00136 
00137     startButton = new QPushButton( tr( "&Start Tests!" ), this );
00138     QWhatsThis::add( startButton, tr( "Click here to perform the selected tests." ) );
00139     connect( startButton, SIGNAL( clicked() ), this, SLOT( run() ) );
00140     vb->addWidget( tests, 2 );
00141 
00142     QHBoxLayout* hb = new QHBoxLayout( vb );
00143     hb->addWidget( startButton, 2 );
00144 
00145     QFile f( QPEApplication::qpeDir() + "share/sysinfo/results" );
00146     if ( f.open( IO_ReadOnly ) )
00147     {
00148         machineCombo = new QComboBox( this );
00149         QWhatsThis::add( machineCombo, tr( "Choose a model to compare your results with." ) );
00150 
00151         QTextStream ts( &f );
00152         while( !ts.eof() )
00153         {
00154             QString machline = ts.readLine();
00155             odebug << "sysinfo: parsing benchmark results for '" << machline << "'" << oendl;
00156             QString resline = ts.readLine();
00157             machines.insert( machline, new QStringList( QStringList::split( ",", resline ) ) );
00158             machineCombo->insertItem( machline );
00159         }
00160         hb->addWidget( machineCombo, 2 );
00161         connect( machineCombo, SIGNAL( activated(int) ), this, SLOT( machineActivated(int) ) );
00162     }
00163 }
00164 
00165 
00166 BenchmarkInfo::~BenchmarkInfo()
00167 {}
00168 
00169 
00170 void BenchmarkInfo::machineActivated( int index )
00171 {
00172     QStringList* results = machines[ machineCombo->text( index ) ];
00173     if ( !results )
00174     {
00175         odebug << "sysinfo: no results available." << oendl;
00176         return;
00177     }
00178     QStringList::Iterator it = results->begin();
00179     test_alu->setText( 2, *(it++) );
00180     test_fpu->setText( 2, *(it++) );
00181     test_txt->setText( 2, *(it++) );
00182     test_gfx->setText( 2, *(it++) );
00183     test_ram->setText( 2, *(it++) );
00184 #ifndef QT_QWS_RAMSES
00185     test_sd->setText( 2, *(it++) );
00186     test_cf->setText( 2, *(it++) );
00187 #endif
00188 }
00189 
00190 
00191 void BenchmarkInfo::run()
00192 {
00193     startButton->setText( "> Don't touch! <" );
00194     qApp->processEvents();
00195     QTime t;
00196 
00197     if ( test_alu->isOn() )
00198     {
00199         int d = round( dhry_main( DHRYSTONE_RUNS ) );
00200         test_alu->setText( 1, QString().sprintf( "%d dhrys", d ) );
00201         test_alu->setOn( false );
00202     }
00203 
00204     if ( test_fpu->isOn() )
00205     {
00206         t.start();
00207         BenchFFT();
00208         test_fpu->setText( 1, QString().sprintf( "%.2f secs", t.elapsed() / 1000.0 ) );;
00209         test_fpu->setOn( false );
00210     }
00211 
00212     if ( test_txt->isOn() )
00213     {
00214         int value = textRendering( TEST_DURATION );
00215         test_txt->setText( 1, QString().sprintf( "%d chars/sec", value / TEST_DURATION ) );
00216         test_txt->setOn( false );
00217     }
00218 
00219     if ( test_gfx->isOn() )
00220     {
00221         int value = gfxRendering( TEST_DURATION );
00222         test_gfx->setText( 1, QString().sprintf( "%.2f gops/sec", value / 4.0 / TEST_DURATION ) ); // 4 tests
00223         test_gfx->setOn( false );
00224     }
00225 
00226     if ( test_ram->isOn() )    // /tmp is supposed to be in RAM on a PDA
00227     {
00228         performFileTest( "/tmp/benchmarkFile.dat", test_ram );
00229     }
00230 
00231 #ifndef QT_QWS_RAMSES
00232     if ( test_cf->isOn() )
00233     {
00234         OStorageInfo storage;
00235         performFileTest( storage.cfPath() + "/benchmarkFile.dat", test_cf );
00236     }
00237 
00238     if ( test_sd->isOn() )
00239     {
00240         OStorageInfo storage;
00241         performFileTest( storage.sdPath() + "/benchmarkFile.dat", test_sd );
00242     }
00243 #endif
00244 
00245     startButton->setText( tr( "&Start Tests!" ) );
00246 }
00247 
00248 
00249 int BenchmarkInfo::textRendering( int seconds )
00250 {
00251     QTime t;
00252     t.start();
00253     int stop = t.elapsed() + seconds * 1000;
00254 
00255     int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 };
00256     int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 };
00257     int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 };
00258     const QString text( "Opie Benchmark Test" );
00259 
00260     int w = QApplication::desktop()->width();
00261     int h = QApplication::desktop()->height();
00262 
00263     srand( time( NULL ) );
00264 
00265     BenchmarkPaintWidget bpw;
00266 
00267     int loops = 0;
00268 
00269     while ( t.elapsed() < stop )
00270     {
00271         int k = rand() % 9;
00272         int s = rand() % 100;
00273         bpw.p.setPen( QColor( rr[ k ], gg[ k ], bb[ k ] ) );
00274         bpw.p.setFont( QFont( "Vera", s ) );
00275         bpw.p.drawText( rand() % w, rand() % h, text, text.length() );
00276         ++loops;
00277     }
00278 
00279     return loops * text.length();
00280 }
00281 
00282 int BenchmarkInfo::gfxRendering( int seconds )
00283 {
00284     int rr[] = { 255, 255, 255, 0, 0, 0, 0, 128, 128 };
00285     int gg[] = { 0, 255, 0, 0, 255, 255, 0, 128, 128 };
00286     int bb[] = { 0, 0, 255, 0, 0, 255, 255, 128, 0 };
00287 
00288     int w = QApplication::desktop()->width();
00289     int h = QApplication::desktop()->height();
00290 
00291     srand( time( NULL ) );
00292 
00293     BenchmarkPaintWidget bpw;
00294 
00295     QTime t;
00296     t.start();
00297     int stop = t.elapsed() + seconds*1000;
00298     int loops = 0;
00299 
00300     while ( t.elapsed() < stop )
00301     {
00302         int k = rand() % 9;
00303         bpw.p.setPen( QColor( rr[ k ], gg[ k ], bb[ k ] ) );
00304         bpw.p.drawLine( rand()%w, rand()%h, rand()%w, rand()%h );
00305         ++loops;
00306     }
00307 
00308     t.restart();
00309     stop = t.elapsed() + seconds*1000;
00310 
00311     while ( t.elapsed() < stop )
00312     {
00313         int k = rand() % 9;
00314         bpw.p.setPen( QColor( rr[ k ], gg[ k ], bb[ k ] ) );
00315         bpw.p.drawArc( rand()%w, rand()%h, rand()%w, rand()%h, 360 * 16, 360 * 16 );
00316         ++loops;
00317     }
00318 
00319     QBrush br1;
00320     br1.setStyle( SolidPattern );
00321     t.restart();
00322     stop = t.elapsed() + seconds*1000;
00323 
00324     while ( t.elapsed() < stop )
00325     {
00326         int k = rand() % 9;
00327         br1.setColor( QColor( rr[ k ], gg[ k ], bb[ k ] ) );
00328         bpw.p.fillRect( rand()%w, rand()%h, rand()%w, rand()%h, br1 );
00329         ++loops;
00330     }
00331 
00332     QPixmap p = Opie::Core::OResource::loadPixmap( "sysinfo/pattern" );
00333     t.restart();
00334     stop = t.elapsed() + seconds*1000;
00335 
00336     while ( t.elapsed() < stop )
00337     {
00338         bpw.p.drawPixmap( rand()%w, rand()%h, p );
00339         ++loops;
00340     }
00341 
00342     return loops;
00343 
00344 }
00345 
00346 const unsigned int FILE_TEST_COUNT = 8000;
00347 const unsigned int FILE_TEST_BLOCKSIZE = 1024;
00348 
00349 void BenchmarkInfo::performFileTest( const QString& fname, OCheckListItem* item )
00350 {
00351     QString filename = fname == "/benchmarkFile.dat" ? QString( "/tmp/bla" ) : fname;
00352     odebug << "performing file test on " << filename << oendl;
00353 
00354     QString writeCommand = QString( "dd if=/dev/zero of=%1 count=%2 bs=%3 && sync" ).arg( filename )
00355                                                                                   .arg( FILE_TEST_COUNT )
00356                                                                                   .arg( FILE_TEST_BLOCKSIZE );
00357     QString readCommand = QString( "dd if=%1 of=/dev/null count=%2 bs=%3").arg( filename )
00358                                                                                   .arg( FILE_TEST_COUNT )
00359                                                                                   .arg( FILE_TEST_BLOCKSIZE );
00360     ::system( "sync" );
00361     odebug << "performing file test on " << filename << oendl;
00362 
00363     int write = 0;
00364     int read = 0;
00365 
00366     QTime time;
00367     time.start();
00368     if ( ::system( writeCommand ) == 0 )
00369     {
00370         write = time.elapsed();
00371     }
00372     else
00373     {
00374         item->setText( 1, tr( "error" ) );
00375         return;
00376     }
00377 
00378     time.restart();
00379     if ( ::system( readCommand ) == 0 )
00380     {
00381         read = time.elapsed();
00382     }
00383     else
00384     {
00385         item->setText( 1, tr( "error" ) );
00386         return;
00387     }
00388 
00389     QFile::remove( filename );
00390     double readSpeed = FILE_TEST_COUNT / ( read / 1000.0 );
00391     QString readUnit = "kB/s";
00392     if ( readSpeed > 1024 )
00393     {
00394         readSpeed /= 1024.0;
00395         readUnit = "MB/s";
00396     }
00397     double writeSpeed = FILE_TEST_COUNT / ( write / 1000.0 );
00398     QString writeUnit = "kb/s";
00399     if ( writeSpeed > 1024 )
00400     {
00401         writeSpeed /= 1024.0;
00402         writeUnit = "MB/s";
00403     }
00404     item->setText( 1, QString().sprintf( "%.2f %s; %.2f %s", readSpeed, readUnit.latin1(), writeSpeed, writeUnit.latin1() ) );
00405     item->setOn( false );
00406 }

Generated on Sat Nov 5 16:17:57 2005 for OPIE by  doxygen 1.4.2