/* mm: mo.m Copyright (C) 2006 Macaulay Institute This file is part of mm, a series of programs to test the effect of various mechanisms for mitigating against floating point issues on memory usage and time. mm is free software; you can redistributed it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. mm 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. (LICENCE file in this directory.) You should have received a copy of the GNU General Public License along with this programl if not, write to the Free Software Fountation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact information: Gary Polhill, Macaulay Institute, Craigiebuckler, Aberdeen, AB15 8QH. United Kingdom g.polhill@macaulay.ac.uk */ #import #import #import #import "common.h" #ifdef DOUBLESIMPLE # import #endif /** * mo should be compiled in several different modes to get the operator * required. By default no operator will be used. To get the operators you * require, compile with -DOPERATOR= where is one of * * 0 -- No operation * 1 -- Addition * 2 -- Subtraction * 3 -- Multiplication * 4 -- Division * 5 -- Less than * 6 -- Equal to * 7 -- More than * 8 -- More than or equal to * 9 -- Not equal to * 10 -- Less than or equal to */ void mo(long n); /** * main */ int main(int argc, char **argv) { int maxarg, minarg, seedarg; #ifdef DOUBLESIMPLE DoubleSimple *init; maxarg = 4; minarg = 3; seedarg = 3; #else maxarg = 3; minarg = 2; seedarg = 2; #endif if(argc < minarg || argc > maxarg) { fprintf(stderr, "Usage: %s %s[]\n", argv[0], #ifdef DOUBLESIMPLE " " // e.g.1 DoubleSimple=0.5 // e.g.2 DoubleEpsilon=0.5~0.0001 #else " " #endif ); fprintf(stderr, "Compiled with operator: "); #if OPERATOR == 0 fprintf(stderr, "NOP\n"); #elif OPERATOR == 1 fprintf(stderr, "ADD\n"); #elif OPERATOR == 2 fprintf(stderr, "SUB\n"); #elif OPERATOR == 3 fprintf(stderr, "MUL\n"); #elif OPERATOR == 4 fprintf(stderr, "DIV\n"); #elif OPERATOR == 5 fprintf(stderr, "LT\n"); #elif OPERATOR == 6 fprintf(stderr, "EQ\n"); #elif OPERATOR == 7 fprintf(stderr, "GT\n"); #elif OPERATOR == 8 fprintf(stderr, "GE\n"); #elif OPERATOR == 9 fprintf(stderr, "NE\n"); #elif OPERATOR == 10 fprintf(stderr, "LE\n"); #else fprintf(stderr, "Unrecognised!\n"); # error Unrecognised OPERATOR macro value #endif return 1; } if(argc == maxarg) { set_seed(argv[seedarg]); } #ifdef DOUBLESIMPLE init = [DoubleSimple parseKeepSameClass: argv[2]]; printf("DoubleSimple parse check. Class: %s, Value: ", [init name]); [init writeAccurately: stdout]; printf("\n"); [init free]; #endif mo(atol(argv[1])); return 0; } /** * mo */ void mo(long n) { #ifdef DOUBLESIMPLE DoubleSimple **vector, *dummy; #else double *vector, dummy; #endif long double start_time, finish_time; long i, j; int fd; void *start, *finish; // Allocate memory #ifdef DOUBLESIMPLE vector = (DoubleSimple **)malloc(n * sizeof(DoubleSimple *)); dummy = [DoubleSimple new]; #else vector = (double *)malloc(n * sizeof(double)); #endif if(vector == NULL) die("memory allocation error: %s\n", strerror(errno)); // Get the random numbers for(i = 0; i < n; i++) { #ifdef DOUBLESIMPLE vector[i] = [DoubleSimple new: drand48()]; #else vector[i] = drand48(); #endif } // Get current process info fd = open_process_info(); start = read_process_info(fd); // Operate on the numbers for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { #ifdef DOUBLESIMPLE [dummy set: vector[i]]; # if OPERATOR == 0 # elif OPERATOR == 1 [dummy add: vector[j]]; # elif OPERATOR == 2 [dummy sub: vector[j]]; # elif OPERATOR == 3 [dummy mul: vector[j]]; # elif OPERATOR == 4 [dummy div: vector[j]]; # elif OPERATOR == 5 [dummy lt: vector[j]]; # elif OPERATOR == 6 [dummy eq: vector[j]]; # elif OPERATOR == 7 [dummy gt: vector[j]]; # elif OPERATOR == 8 [dummy ge: vector[j]]; # elif OPERATOR == 9 [dummy ne: vector[j]]; # elif OPERATOR == 10 [dummy le: vector[j]]; # else # error Unrecognised OPERATOR macro value # endif #else dummy = # if OPERATOR == 0 vector[i], vector[j]; # elif OPERATOR == 1 (vector[i] + vector[j]); # elif OPERATOR == 2 (vector[i] - vector[j]); # elif OPERATOR == 3 (vector[i] * vector[j]); # elif OPERATOR == 4 (vector[i] / vector[j]); # elif OPERATOR == 5 (vector[i] < vector[j]) ? 1.0 : 0.0; # elif OPERATOR == 6 (vector[i] == vector[j]) ? 1.0 : 0.0; # elif OPERATOR == 7 (vector[i] > vector[j]) ? 1.0 : 0.0; # elif OPERATOR == 8 (vector[i] >= vector[j]) ? 1.0 : 0.0; # elif OPERATOR == 9 (vector[i] != vector[j]) ? 1.0 : 0.0; # elif OPERATOR == 10 (vector[i] <= vector[j]) ? 1.0 : 0.0; # else (0.0); # error Unrecognised OPERATOR macro value # endif #endif } } // Read the current process info finish = read_process_info(fd); close_process_info(fd); // Display process information start_time = get_time_stamp(start); finish_time = get_time_stamp(finish); printf("Time taken for %lld %s operations: %Lg seconds\n", (long long)n * (long long)n, #if OPERATOR == 0 "NOP", #elif OPERATOR == 1 "ADD", #elif OPERATOR == 2 "SUB", #elif OPERATOR == 3 "MUL", #elif OPERATOR == 4 "DIV", #elif OPERATOR == 5 "LT", #elif OPERATOR == 6 "EQ", #elif OPERATOR == 7 "GT", #elif OPERATOR == 8 "GE", #elif OPERATOR == 9 "NE", #elif OPERATOR == 10 "LE", #else "unrecognised!", # error Unrecognised OPERATOR macro value #endif finish_time - start_time); printf("Size of process in Kbytes: %ld\n", get_memory_usage(finish)); printf("Process info for checking data structure read correctly:\n\t" "Start:\n"); printf("\t\tPID: %ld, PPID: %ld, UID: %ld, EUID: %ld\n", get_pr_pid(start), get_pr_ppid(start), get_pr_uid(start), get_pr_euid(start)); printf("\t\tExec: %s, args: %d\n", get_pr_name(start), get_pr_argc(start) - 1); printf("\tFinish:\n"); printf("\t\tPID: %ld, PPID: %ld, UID: %ld, EUID: %ld\n", get_pr_pid(finish), get_pr_ppid(finish), get_pr_uid(finish), get_pr_euid(finish)); printf("\t\tExec: %s, args: %d\n", get_pr_name(finish), get_pr_argc(finish) - 1); // Free the memory #ifdef DOUBLESIMPLE [dummy free]; for(i = 0; i < n; i++) { [vector[i] free]; } #endif free(vector); }