The benchmark:
/*
* test.c - Simulate workloads that load the CPU differently
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* This workload spawns threads which request for allocation of a
* memory chunk,write to it and free it.The duty cycle of these threads
* can be varied.The idea is to simulate tasks which load the cpu
* to different extents.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "malloc.h"
/* Variable entities */
static unsigned int seconds;
static unsigned int threads;
static unsigned int mem_chunk_size;
static unsigned int sleep_at;
static unsigned int sleep_interval;
typedef size_t mem_slot_t;/* 8 bytes */
static unsigned int slot_size = sizeof(mem_slot_t);
/* Other parameters */
static volatile int start;
static time_t start_time;
static unsigned int records_read;
pthread_mutex_t records_count_lock = PTHREAD_MUTEX_INITIALIZER;
static unsigned int write_to_mem(void)
{
int i, j;
mem_slot_t *scratch_pad, *temp;
mem_chunk_size = slot_size * 256;
mem_slot_t *end;
/* The below two parameters ensure that it is 10% workload
* with a duty cycle of 10ms.The number of records read in
* 1s without sleep was observed and appropriately calculated
* for 1ms.This number turned out to be 1228.
*/
sleep_at = 1228; /* sleep for every 1228 records */
sleep_interval = 9000; /* sleep for 9 ms */
for (i=0; start == 1; i++)
{
scratch_pad = (mem_slot_t *)malloc(mem_chunk_size);
if (scratch_pad == NULL) {
fprintf(stderr,"Could not allocate memory\n");
exit(1);
}
end = scratch_pad + (mem_chunk_size / slot_size);
for (temp = scratch_pad, j=0; temp < end; temp++, j++)
*temp = (mem_slot_t)j;
free(scratch_pad);
if (sleep_at && !(i % sleep_at))
usleep(sleep_interval);
}
return (i);
}
static void *
thread_run(void *arg)
{
unsigned int records_local;
/* Wait for the start signal */
while (start == 0);
records_local = write_to_mem();
pthread_mutex_lock(&records_count_lock);
records_read += records_local;
pthread_mutex_unlock(&records_count_lock);
return NULL;
}
static void start_threads()
{
double diff_time;
unsigned int i;
int err;
threads = 8;
seconds = 10;
pthread_t thread_array[threads];
for (i = 0; i < threads; i++) {
err = pthread_create(&thread_array[i], NULL, thread_run, NULL);
if (err) {
fprintf(stderr, "Error creating thread %d\n", i);
exit(1);
}
}
start_time = time(NULL);
start = 1;
sleep(seconds);
start = 0;
diff_time = difftime(time(NULL), start_time);
for (i = 0; i < threads; i++) {
err = pthread_join(thread_array[i], NULL);
if (err) {
fprintf(stderr, "Error joining thread %d\n", i);
exit(1);
}
}
printf("%u records/s\n",
(unsigned int) (((double) records_read)/diff_time));
}
int main()
{
start_threads();
return 0;
}
Regards
Preeti U Murthy