Improve measurement accuracy

This patch replaces the jiffies thread in 'sd_card/omap4/bench' calls to
'Timer::Session::elapsed_ms()'. This way, we use wall-clock time for the
measurements. Depending on the load of the rest of the system, the
previous version used to accumulate the inaccuracy for each 'msleep'
call.
This commit is contained in:
Norman Feske 2012-07-25 17:52:20 +02:00
parent 693922d789
commit e9497a183f

View File

@ -8,85 +8,55 @@
#include <base/sleep.h>
#include <base/printf.h>
#include <timer_session/connection.h>
#include <os/attached_ram_dataspace.h>
/* local includes */
#include <driver.h>
class Jiffies_thread : Genode::Thread<4096>
{
private:
Timer::Connection _timer;
Genode::Lock mutable _lock;
Genode::size_t _milliseconds;
enum { MS_PER_STEP = 10 };
void entry()
{
for (;;) {
_timer.msleep(MS_PER_STEP);
{
Genode::Lock::Guard guard(_lock);
_milliseconds += MS_PER_STEP;
}
}
}
public:
Jiffies_thread() : _milliseconds(0) { start(); }
Genode::size_t milliseconds() const
{
Genode::Lock::Guard guard(_lock);
return _milliseconds;
}
void reset()
{
Genode::Lock::Guard guard(_lock);
_milliseconds = 0;
}
};
/*
* \param total_size total number of bytes to read
* \param request_size number of bytes per request
*/
static void test_read(Block::Driver &driver,
Jiffies_thread &jiffies,
char *out_buffer,
Genode::size_t total_size,
Timer::Session &timer,
char *buffer_virt,
Genode::addr_t buffer_phys,
Genode::size_t buffer_size,
Genode::size_t request_size)
{
using namespace Genode;
PLOG("read: request_size=%zd bytes", request_size);
jiffies.reset();
size_t const time_before_ms = timer.elapsed_ms();
size_t num_requests = total_size / request_size;
size_t num_requests = buffer_size / request_size;
for (size_t i = 0; i < num_requests; i++)
{
size_t const block_count = request_size / driver.block_size();
addr_t const block_number = i*block_count;
driver.read(block_number, block_count, out_buffer + i*request_size);
if (driver.dma_enabled()) {
driver.read_dma(block_number, block_count,
buffer_phys + i*request_size);
} else {
driver.read(block_number, block_count,
buffer_virt + i*request_size);
}
}
size_t const duration_ms = jiffies.milliseconds();
size_t const time_after_ms = timer.elapsed_ms();
size_t const duration_ms = time_after_ms - time_before_ms;
/*
* Convert bytes per milliseconds to kilobytes per seconds
*
* (total_size / 1024) / (duration_ms / 1000)
*/
size_t const total_size_kb = total_size / 1024;
size_t const throughput_kb_per_sec = (1000*total_size_kb) / duration_ms;
size_t const buffer_size_kb = buffer_size / 1024;
size_t const throughput_kb_per_sec = (1000*buffer_size_kb) / duration_ms;
PLOG(" -> duration: %zd ms", duration_ms);
PLOG(" throughput: %zd KiB/sec", throughput_kb_per_sec);
@ -99,18 +69,27 @@ int main(int argc, char **argv)
printf("--- OMAP4 SD card benchmark ---\n");
static Block::Omap4_driver driver;
static Jiffies_thread jiffies;
bool const use_dma = true;
long const block_sizes[] = {
static Block::Omap4_driver driver(use_dma);
static Timer::Connection timer;
long const request_sizes[] = {
512, 1024, 2048, 4096, 8192, 16384, 32768, 0 };
enum { TOTAL_SIZE = 10*1024*1024 };
/* total size of communication buffer */
size_t const buffer_size = 10*1024*1024;
static char buffer[TOTAL_SIZE];
/* allocate read buffer */
static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, false);
for (unsigned i = 0; block_sizes[i]; i++)
test_read(driver, jiffies, buffer, TOTAL_SIZE, block_sizes[i]);
char * const buffer_virt = buffer.local_addr<char>();
addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr();
for (unsigned i = 0; request_sizes[i]; i++)
test_read(driver, timer, buffer_virt, buffer_phys, buffer_size,
request_sizes[i]);
printf("--- OMAP4 SD card benchmark finished ---\n");
sleep_forever();