Documente Academic
Documente Profesional
Documente Cultură
This assignment compares the performance and efficiency of two programs with identical
functionality implemented by way of multiple processes in one program, compared to multiple
threads in the other program.
Test B (Same as Test A, but with 1000x more file I/O) ................................... page 9
Test D (Same as Test B, but on dedicated server running Ubuntu Server) ......... page 15
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 1 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Introduction
This assignment compares the performance and efficiency of two programs with identical
functionality implemented by way of multiple processes in one program, compared to multiple
threads in the other program. The functionality in each process, and in each thread, consists of a
prime number decomposition algorithm to perform processor-intensive computations, followed by
local file input/output.
Methodology
The multiple process program processes.c is included on the accompanying DVD, along with its
corresponding source code listing at “processes.c program listing.pdf”.
The multiple thread program threads.c is also included on the accompanying DVD, along with its
corresponding source code listing at “threads.c program listing.pdf”.
Each of the programs was written in ANSI C, compiled and linked with gcc version 4.4, and then
run on Ubuntu version 10 Linux. None of the work in this assignment was done on Microsoft
Windows.
The pseudo-code design for both processes.c and threads.c is included in the Appendix.
The prime number decomposition algorithm was borrowed from rosettacode.org. A single integer
is passed to this algorithm, which then calculates the lowest prime numbers which must be
multiplied together to get the product equal to this integer. The GNU multi-precision library
(“gmp”) is used in this algorithm. The more complexity that is required with regards to the prime
numbers to be discovered, the more processor computations are required, and thus the more
elapsed time is required.
The integer passed to each process or thread is determined by command line arguments when the
program is started. Starting either program with 3 different numbers (integers) on the command
line will result in 3 separate processes or threads being created, each with one of the command
line numbers as the integer to be decomposed. Both programs are designed to accept between 3
and 9 numbers, meaning that a minimum of 3 and a maximum of 9 processes or threads will be
created.
The file input/output involves the creation of a unique write-able file, followed by a variable
number of writes (using the fputs() function) into the file, and an equal number of reads (using
fgets() function) from the file. When finished, the file is then closed. The number of writes and
reads defaults to 10, but can be changed by using the --ioloops= command line parameter when
starting up the program. Specifying --ioloops=6 for example, will cause each process or thread to
go through 1,000,000 (10^6) writes and reads.
Four tests were run and tabulated for this assignment, with each test comparing a sampling of
start times and run times for five simultaneous child processes versus five simultaneous threads.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 2 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Three of the tests were done in order to measure the impact of changing some of the functionality
done by each process and by each thread; the fourth test was done in order to measure the
impact of changing the hardware and operating system environment.
The processes were created by way of the C language fork() command. The threads were
implemented using the C language POSIX pthread library. The start times were calculated by
recording the system time just before either the fork() or pthread_create() function calls, and
then passing this system time to the function run by the child process or the thread. The first step
in each process and in each thread was to calculate the elapsed time at that point in time since
the system time passed to it. This elapsed time was what we refer to as the “start time” and it is a
measure of how long it took to get a process or a thread started.
Run times were calculated as the very last step in each process and in each thread. The system
time was recorded at the end of the process or thread, and from that the elapsed time since the
start of the process or thread was calculated, to be the “run time”.
Total times were simply calculated as the sum of the start time and run time of each process or
thread.
A sampling of each test run was done because of the variations encountered in both start times
and run times. Averages, medians, and variances were thus calculated based on the samples.
Each test was run 5 times for the multiple process program (“a1p”) and 5 times for the multiple
thread program (“a1t”), with all known controllable conditions and variables the same for each
sample.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 3 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
This first test was run on an Xubuntu 10.04 32-bit Desktop VM in VMware Workstation on a
Microsoft Windows 7 Ultimate desktop. The VM was configured to use 640MB of RAM, 20GB of
hard disk, and 4 processors, as shown below:
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 4 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
An example test run was done on January 28, 2011 at 19:17:27 PST, as shown below. The
command line used to start the multiple threads program was:
The 5 numbers on the command line correspond to the 5 threads started. The –ioloops=1
argument corresponds to 10 file I/O loops being performed in each thread.
It is readily apparent that thread scheduling performed by the Ubuntu Linux 2.6.32-28 kernel is
not predictable – at least in this VM environment. The program logic in threads.c (see line 156)
shows that each of the threads would have been started in order from 1 to 5. However, execution
of thread 3 is the first to reach the printf() statement (at line 186) which shows its start time of
0.0005 seconds with the number 2050700031. Thread 3 is followed by threads 1, 2, 5 and then 4
to get to this point in the program/thread.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 5 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple threaded Test A. Start times for each
thread varied from 0.0004 to 0.0021 seconds, with an average of 0.0009 seconds. Total start
times for all threads varied from 0.0039 to 0.0057 seconds, with an average of 0.0046 seconds.
Run times varied dramatically. Thread 1, for example, which was decomposing the same integer
998 each time, and performing the same file I/O each time, took only 0.0030 seconds in one
sample, but 3.0784 seconds in another. That is over a 1000x variation in thread run time. It is
likely that thread scheduling or other thread overhead is negatively impacting the performance of
threads in this environment.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 6 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Next the multiple process testing was done, as shown below. Note the command line used to start
this program is exactly the same as for the multiple thread example shown previously, other than
the program name here is ./a1p rather than ./a1t.
It is interesting to note that process scheduling performed by the same Ubuntu Linux 2.6.32-28
kernel is also unpredictable in this VM environment. Processes 1 through 5 are fork()ed in
sequence in threads.c (line 158) and yet they appear in sequence as 2, 3, 5, 4 and then 1.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 7 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple process Test A. Start times for each
process varied from 0.0008 to 0.0053 seconds, with an average of 0.0019 seconds. This is over
double the average start time of 0.0009 seconds recorded for the multiple thread samples. Total
start times for all processes varied from 0.0050 to 0.0143 seconds, with an average of 0.0094
seconds – again over double the average total start time of 0.0046 seconds for the multiple
thread samples.
Process with 10 file I/O Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals
loops averages
Run times, however, paint a very different picture for processes: they are relatively stable, and
considerably faster than threads. The average for all process run time samples is 0.7123 seconds
compared to 2.1462 seconds for all thread run time samples: approximately 3 times faster. These
averages across all processes/threads, however, actually mask some large disparities. Process 3 is
only marginally faster than Thread 3 on average (run time of 3.1492 vs. 3.1988 seconds).
However, Process 1 is 234 faster than Thread 1 despite doing the exact same work; Process 2 is
6.2 times faster than Thread 2; Process 4 is 330 times faster than Thread 4; and Process 5 is 420
times faster than Thread 5. These are enormous differences in performance.
Since the run times in these test samples make up an average of 99.73% of the total time taken
by processes (0.7123 of total 0.7142 seconds) and an average of 99.96% of the total time taken
by threads (2.1462 of total 2.1471 seconds) the run time advantages of processes are far more
significant in the overall evaluation than the start time advantages of threads.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 8 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
The second test was run on the same Xubuntu 10.04 Desktop VM in VMware Workstation on a
Microsoft Windows 7 Ultimate desktop, with the amount of file input/output increased 1000 times.
The intention in this test was to measure the impact of increasing the amount of file input/output
activity, while keeping everything else constant.
An example test run was done on January 30, 2011 at 5:39:07 PST, as shown below. The
command line used to start the multiple processes program was:
This will generate 100,000 file input/output operations, rather than the 10 done in Test A.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 9 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple threaded Test B. Start times for each
thread varied from 0.0004 to 0.0022 seconds, with an average of 0.0008 seconds. Total start
times for all threads varied from 0.0037 to 0.0050 seconds, with an average of 0.0042 seconds.
All of these start times, as expected, were within 10-15% of the start times measured in Test A.
Run times again varied dramatically. None were as low as the lowest run times measured in Test
A, where 6 run times were measured at less than 0.0100 seconds. In Test B the lowest 6 run
times were all below about 0.52 seconds, which is about 52 times slower.
Oddly, however, Threads 1, 2 and 5 had faster run time averages in Test B than in Test A. These
results make no sense, except in the context of apparent issues with thread scheduling or other
thread overhead impacting the run time performance of threads in this environment.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 10 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple process Test B. Start times for each
process varied from 0.0006 to 0.0131 seconds, with an average of 0.0040 seconds. This is 5
times the average start time of 0.0008 seconds recorded for the multiple thread samples in Test
B. Total start times for all processes varied from 0.0098 to 0.0315 seconds, with an average of
0.0201 seconds – again about 5 times the average total start time of 0.0042 seconds for the
multiple thread samples in Test B.
These process start times were just over 2 times longer than the process start times in Test A,
which was unexpected, and would require further investigation to understand.
Process with 100,000 Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals
file I/O loops averages
Run time samples for Test B were again relatively stable within each process, as was seen in Test
A. Run times were also longer in Test B across the board, as would be expected. The average
increase in run times resulting from the significant increase in file input/output activity was about
4%.
However, it is not obvious why run time increases were so large for processes 1, 4 and 5 while
being only slightly longer for processes 2 and 3. Further investigation would be required to better
understand these differences.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 11 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
The third test was again run on the same Xubuntu 10.04 Desktop VM in VMware Workstation on a
Microsoft Windows 7 Ultimate desktop, with no file input/output at all. The intention in this test
was to measure the impact of doing only processor work, with no file or disk activity, while
keeping everything else constant.
An example test run was done on January 30, 2011 at 5:35:58 PST, as shown below. The
command line used to start the multiple processes program was:
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 12 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple threaded Test C. Start times for each
thread varied from 0.0004 to 0.0029 seconds, with an average of 0.0009 seconds. Total start
times for all threads varied from 0.0031 to 0.0093 seconds, with an average of 0.0047 seconds.
All of these start times, as expected, were within close range of the start times previously
measured in Tests A and B.
Run times again varied dramatically, but with values quite similar to Test A. There were 4 very
fast run times below 0.0029 seconds, another 7 run times in the range of 0.38 to 0.39 seconds,
and the remaining run times in the range of 3.09 to 3.65 seconds.
Test A produced 6 very fast run times below 0.0093 seconds, another 3 run times at about 0.38
seconds, and all the remaining run times in the range of 3.07 to 3.58 seconds.
Oddly, again, Threads 3, 4 and 5 had slower run time averages in Test C than in Test A, despite
doing less work. These results again make no sense, except in the context of apparent issues with
thread scheduling or other thread overhead impacting the run time performance of threads in this
environment.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 13 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple process Test C. Start times for each
process varied from 0.0006 to 0.0023 seconds, with an average of 0.0013 seconds. These were
the fastest process start times measured to this point, and were only about 1.4 times slower than
the average 0.0009 second start time for threads in Test C. Total start times for all processes
varied from 0.0056 to 0.0074 seconds, with an average of 0.0063 seconds – about one third
faster than the 0.0094 seconds for processes in Test A, and only 1.3 times slower than the 0.0047
seconds for threads in Test C.
Whether these differences in start times are normal variations, or whether they are impacted by
the amount of file input/output activity performed within each process is a question for further
research. There appears to be evidence for the latter possibility, even if the reasons are not
immediately obvious.
Process
Process with no file I/O Child 1 Child 2 Child 3 Child 4 Child 5 Totals
averages
Run time samples for Test C were very stable within each process, pointing to the possibility the
file input/output activity increased the variability in run times. Run times were also mostly shorter
in Test C across the board, as would be expected. The average decrease in run times resulting
from the absence of any file input/output activity was about 2.5% compared to Test A, and about
6% compared to Test B.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 14 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
The last test in this assignment was run on a dedicated, 8-processor Internet server running 64-
bit Ubuntu 10.04 Server with Linux kernel 2.6.32-27. The intention in this test was to measure
the impact of a more powerful server, while keeping everything else the same as in Test B.
An example test run was done on January 30, 2011 at 16:22:57 EST, as shown below. The
command line used to start the multiple processes program was the same as that in Test B:
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 15 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple threaded Test D. Start times for each
thread varied from just 0.0001 to 0.0003 seconds, with an average of 0.0001 seconds. Total start
times for all threads varied from just 0.0006 to 0.0007 seconds, with an average of 0.0006
seconds. These were 7-8 times faster than any of the three previous Tests, which produced
average total start times of 0.0042, 0.0046 and 0.0047 seconds. A more powerful environment
obviously had a significant impact in reducing thread start times.
Run times again displayed the same tri-level grouping of measurements which has been observed
in all previous thread Tests A, B and C. There were 6 fastest run times in the range of 0.099 to
0.168 seconds, another 8 run times in the range of 0.4190 to 0.4505 seconds, and the remaining
run times in the range of 2.62 to 2.96 seconds. Again, as well, there were large variations
observed in run times for all Threads except for Thread 3. Thread 3 has been observed to
consistently produce the longest run times, for both threads and processes, and it is presumed
that this is caused by the prime number decomposition algorithm for the number 2050700031 in
Thread 3 being the most computationally expensive. The reason for this producing less variability
in thread run times, however, is not known at this time.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 16 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Here is a summary of the 5 samples taken for the multiple process Test D. Start times for each
process were just 0.0002 in 24 of the 25 samples. These were double the start times for the
threads in Test D, but far less than the average 0.0040 second start times for processes in Test B.
Total start times for all processes were just 0.0009 to 0.0010 seconds, which compares favourably
to the 0.0006 to 0.0007 seconds for the threads in Test D, and is 20 times faster than the total
start time average for processes in Test B.
Process with 100,000 Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals
file I/O loops averages
Run times were stable and faster for processes 2, 3, 4 and 5 compared to Test B, which was
expected. Average run time totals were about 16-17% faster than in Test B.
Process 1, however, presented an anomaly with run times consistently and significantly slower
than Test B. Further investigation would be required to determine the possible reasons for this
result.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 17 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Four different tests were conducted for this assignment to compare the use of multiple,
concurrent threads versus multiple, concurrent processes. Each of the threads in one program -
and each of the concurrent processes in the other program - performed processor intensive tasks
followed by file input/output intensive tasks that were different from each of the other concurrent
threads and processes. But each thread in one program performed exactly the same tasks as their
corresponding process in the other program, such that the only difference between them was their
implementation in either a thread or a process.
Source code for each of the programs is included on the accompanying DVD for confirmation of
this design.
Timing measurements were done at three places in each program. First, the system time was
recorded just before each thread or each process was started. This time snapshot was passed to
each thread and each process, and used to calculate the “start time” for each thread and each
process, by comparing it to the second timing measurement done as the first step in each thread
and in each process. Finally, the system time was again recorded as the last step in each thread
and in each process, in order to calculate the “run time” - from start to finish - for each thread
and for each process.
These timing measurements showed that the start times for threads is significantly faster than for
processes: between 1.5 and 5 times faster.
However, timing measurements for run times was exactly the opposite, with processes completing
about 2-3 times faster, on average, than threads.
Given that start times in our tests represented much less than 1% of the total time to both start
and finish each thread and each process, the advantage of threads being faster to launch is not
significant, and for all intents and purposes, irrelevant. For threads that can complete their
intended purpose in a very small increment of time, this start up advantage may be useful.
However, in this assignment it was not.
There was evidence that threads in 10-15% of the samples were much faster than in other
samples, and it is presumed that fine tuning of thread scheduling may be possible to provide more
consistent and faster processing times for threads. However, none of the fastest threads
measured were as fast as the fastest processes. Further, the range of timing measurements for
processes was much smaller than for threads, pointing to the likelihood that – at the very least -
process scheduling in the Linux kernels used in this assignment is much more refined and reliable
than thread scheduling.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 18 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Appendix
/ root directory:
COMP8005_Assignment1_final.docx (this file)
COMP8005_Assignment1_final.doc (doc version of this file)
COMP8005_Assignment1_final.pdf (pdf version of this file)
COMP8005_Assignment1_timing_analysis.xls (Excel spreadsheet timing analysis)
COMP8005_Assignment1_timing_analysis.pdf (pdf version of timing analysis spreadsheet)
Ass1-201101-PTS.pdf (copy of assignment description)
a1p (multiple process executable)
a1t (multiple thread executable)
child*.txt (files created by a1p)
thread*.txt (files created by a1t)
processes.c program listing.pdf (listing of processes.c source code)
threads.c program listing.pdf (listing of threads.c source code)
/src/ directory:
gmp.h (c header file for gmp library)
pthread.h (c header file for pthread library)
multi.c (c source code used as basis for threads.c)
pipe_nonblocking.c (c source code used as basis for processes.c)
primedecompose.c (c source code for decompose() function)
primedecompose.h (c header file for decompose() function)
processes.c (c source code for multiple process program)
threads.c (c source code for multiple thread program)
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 19 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Define prototypes;
Define globals;
Main() function {
Get system time using gettimeofday();
Define variables;
Verify and save command-line arguments;
For ( each child process to be fork()ed ) {
Get system time using gettimeofday();
fork();
if ( child process ) {
do child() function;
}
do parent() function;
}
Get system time using gettimeofday();
Use printf() to display program run time;
Exit;
}
Parent() function {
Return; // do nothing
}
Child() function {
Get system time using gettimeofday();
Calculate and display start time for this process;
Define variables;
Use printf() to display process start time and integer passed to child();
If ( doing prime decomposition ) {
Do calc() with integer passed to child();
}
If ( doing file input/output ) {
Fopen() file in write mode;
For ( number of file i/o loops passed to child() ) {
Do write to file with fputs();
Do read from file with fgets();
}
Fclose() file;
}
Get system time using gettimeofday();
Use printf() to display child process run time;
Exit;
}
Calc() function {
// as per rosettacode.org
}
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 20 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Define prototypes;
Define globals;
Main() function {
Get system time using gettimeofday();
Define variables;
Verify and save command-line arguments;
For ( each thread to be created ) {
Load thread_data_array[] with values to be passed to thread;
Get system time using gettimeofday();
Use pthread_create() to create the next thread and pass thread()
function;
}
Get system time using gettimeofday();
Use printf() to display program run time;
Use pthread_exit() to exit program when all threads are done;
}
Thread() function {
// to be executed by each new thread
Get system time using gettimeofday();
Calculate and display start time for this thread;
Define variables;
Use printf() to display thread start time and integer passed to thread();
If ( doing prime decomposition ) {
Do mutex lock();
Do calc() with integer passed to thread();
Do mutex unlock();
}
If ( doing file input/output ) {
Fopen() file in write mode;
For ( number of file i/o loops passed to thread() ) {
Do write to file with fputs();
Do read from file with fgets();
}
Fclose() file;
}
Get system time using gettimeofday();
Use printf() to display thread run time;
Exit;
}
Calc() function {
// as per rosettacode.org
}
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 21 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Bibliography
[1] Xubuntu: Linux for human beings. Reference found on “xubuntu.org” Internet site at
http://www.xubuntu.org/about/ on December 2, 2010.
[6] YoLinux Tutorial: Fork, Exec and Process Control. Reference found on “yolinux.com” Internet
site at http://yolinux.com/TUTORIALS/ForkExecProcesses.html on January 28, 2011.
[7] Introduction to Parallel Computing. Blaise Barney, Lawrence Livermore National Laboratory.
Reference found on “computing.llnl.gov” Internet site at
https://computing.llnl.gov/tutorials/parallel_comp/ on January 22, 2011.
[8] POSIX Threads Programming. Blaise Barney, Lawrence Livermore National Laboratory.
Reference found on “computing.llnl.gov” Internet site at
https://computing.llnl.gov/tutorials/pthreads/ on January 22, 2011.
[9] The GNU Multiple Precision Arithmetic Library. Reference found on “gmplib.org” Internet site
at http://gmplib.org/ on January 22, 2011.
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 22 of 23
BCIT Computing and Information Technology
COMP 8005 Network and Security Applications Development
Due Date: February 1, 2011
Author: Arthur (Wesley) Kenzie A00242330
Assignment 1: Multi-Process versus Multi-Threaded Program Analysis (Final Version)
______________________________________________________________________________
Credits
______________________________________________________________________________
Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 23 of 23
COMP 8005, Assignment 1 January 2011
A B C D E F G H I
1 Test A
2
file I/O loops in each Process
10 10 10 10 10
3 or Thread ...
4
Process
Process
Process with 10 file I/O Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals Totals vs
loops averages
5 Threads
6 run 1 start times 0.0008 0.0009 0.0010 0.0017 0.0006 0.0010 0.0050 87.7%
7 run 2 start times 0.0010 0.0018 0.0038 0.0053 0.0024 0.0029 0.0143 366.7%
8 run 3 start times 0.0010 0.0012 0.0010 0.0016 0.0017 0.0013 0.0065 151.2%
9 run 4 start times 0.0011 0.0013 0.0012 0.0017 0.0024 0.0015 0.0077 145.3%
10 run 5 start times 0.0035 0.0043 0.0015 0.0023 0.0021 0.0027 0.0137 342.5%
11 Process average start times 0.0015 0.0019 0.0017 0.0025 0.0018 0.0019 0.0094 203.4%
12 run 1 run times 0.0065 0.4175 3.1952 0.0028 0.0056 0.7255 3.6276 22.9%
13 run 2 run times 0.0031 0.4010 3.1160 0.0032 0.0062 0.7059 3.5295 36.3%
14 run 3 run times 0.0016 0.3959 3.1833 0.0032 0.0053 0.7179 3.5893 27.3%
15 run 4 run times 0.0018 0.3921 3.1176 0.0041 0.0081 0.7047 3.5237 51.7%
16 run 5 run times
run 5 run times 0 0018
0.0018 0 3895
0.3895 3 1341
3.1341 0 0077
0.0077 0 0052
0.0052 0 7077
0.7077 3 5383
3.5383 43 3%
43.3%
17 Process average run times 0.0030 0.3992 3.1492 0.0042 0.0061 0.7123 3.5617 33.2%
18 Process average total times 0.0044 0.4011 3.1509 0.0067 0.0079 0.7142 3.5711 33.3%
19
Thread
Thread with 10 file I/O Thread
Thread 1 Thread 2 Thread 3 Thread 4 Thread 5 Totals Totals vs
loops averages
20 Processes
21 run 1 start times 0.0021 0.0011 0.0005 0.0009 0.0011 0.0011 0.0057 114.0%
22 run 2 start times 0.0010 0.0008 0.0006 0.0004 0.0011 0.0008 0.0039 27.3%
23 run 3 start times 0.0009 0.0009 0.0006 0.0004 0.0015 0.0009 0.0043 66.2%
24 run 4 start times 0.0010 0.0009 0.0007 0.0006 0.0021 0.0011 0.0053 68.8%
25 run 5 start times 0.0009 0.0007 0.0006 0.0013 0.0005 0.0008 0.0040 29.2%
26 Thread average start times 0.0012 0.0009 0.0006 0.0007 0.0013 0.0009 0.0046 49.2%
27 run 1 run times 3.0784 3.4788 3.0804 3.0858 3.0845 3.1616 15.8079 435.8%
28 run 2 run times 0.0030 3.4893 3.1106 0.0045 3.1092 1.9433 9.7166 275.3%
29 run 3 run times 0.0032 3.4758 3.0950 3.4775 3.0997 2.6302 13.1512 366.4%
30 run 4 run times 0.0040 3.5864 3.2055 0.0093 0.0080 1.3626 6.8132 193.4%
31 run 5 run times 0.3874 0.3855 3.5024 0.3860 3.5050 1.6333 8.1663 230.8%
32 Thread average run times 0.6952 2.8832 3.1988 1.3926 2.5613 2.1462 10.7310 301.3%
33 Thread average total times
Thread average total times 0 6964
0.6964 2 8840
2.8840 3 1994
3.1994 1 3933
1.3933 2 5625
2.5625 2 1471
2.1471 10 7357
10.7357 300 6%
300.6%
34
Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 1 of 5
COMP 8005, Assignment 1 January 2011
A B C D E F G H I
35 Test B
36
file I/O loops in each Process
100,000 100,000 100,000 100,000 100,000
37 or Thread ...
38
Process
Process
Process with 100,000 file Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals Totals vs
I/O loops averages
39 Threads
40 run 1 start times 0.0017 0.0013 0.0131 0.0038 0.0101 0.0060 0.0300 810.8%
41 run 2 start times 0.0019 0.0029 0.0082 0.0072 0.0113 0.0063 0.0315 768.3%
42 run 3 start times 0.0009 0.0007 0.0029 0.0026 0.0027 0.0020 0.0098 196.0%
43 run 4 start times 0.0007 0.0006 0.0014 0.0018 0.0100 0.0029 0.0145 402.8%
44 run 5 start times 0.0008 0.0008 0.0006 0.0014 0.0112 0.0030 0.0148 321.7%
45 Process average start times 0.0012 0.0013 0.0052 0.0034 0.0091 0.0040 0.0201 479.0%
46 run 1 run times 0.0214 0.4396 3.3315 0.0153 0.0259 0.7667 3.8337 60.6%
47 run 2 run times 0.0218 0.4153 3.2627 0.0248 0.0201 0.7489 3.7447 27.5%
48 run 3 run times 0.0145 0.4213 3.2047 0.0170 0.0270 0.7369 3.6845 28.4%
49 run 4 run times 0.0102 0.4120 3.1892 0.0109 0.0123 0.7269 3.6346 40.1%
50 run 5 run times
run 5 run times 0 0103
0.0103 0 3982
0.3982 3 2068
3.2068 0 0102
0.0102 0 0118
0.0118 0 7275
0.7275 3 6373
3.6373 29 4%
29.4%
51 Process average run times 0.0156 0.4173 3.2390 0.0156 0.0194 0.7414 3.7070 34.1%
52 Process average total times 0.0168 0.4185 3.2442 0.0190 0.0285 0.7454 3.7271 34.2%
53 this vs Test A 379.3% 104.3% 103.0% 282.7% 359.6% 104.4%
54
Thread
Thread with 100,000 file I/O Thread
Thread 1 Thread 2
Thread 1 Thread 2 Thread 3
Thread 3 Thread 4
Thread 4 Thread
Thread 5
5 Totals Totals vs
Totals vs
loops averages
55 Processes
56 run 1 start times 0.0011 0.0009 0.0007 0.0006 0.0004 0.0007 0.0037 12.3%
57 run 2 start times 0.0010 0.0008 0.0006 0.0006 0.0011 0.0008 0.0041 13.0%
58 run 3 start times 0.0008 0.0008 0.0007 0.0005 0.0022 0.0010 0.0050 51.0%
59 run 4 start times 0.0005 0.0008 0.0005 0.0010 0.0008 0.0007 0.0036 24.8%
60 run 5 start times 0.0011 0.0008 0.0007 0.0014 0.0006 0.0009 0.0046 31.1%
61 Thread average start times 0.0009 0.0008 0.0006 0.0008 0.0010 0.0008 0.0042 20.9%
62 run 1 run times 0.5144 0.7985 3.8853 0.5749 0.5576 1.2661 6.3307 165.1%
63 run 2 run times 0.7624 0.7624 4.0316 4.0262 4.0591 2.7283 13.6417 364.3%
64 run 3 run times 0.2476 0.7075 4.0049 4.0122 4.0230 2.5990 12.9952 352.7%
65 run 4 run times 0.5224 3.9509 3.5664 0.5247 0.5067 1.8142 9.0711 249.6%
66 run 5 run times 0.4274 4.0277 3.5258 4.0281 0.3810 2.4780 12.3900 340.6%
67 Thread average run times
Thread average run times 0 4948
0.4948 2 0494
2.0494 3 8028
3.8028 2 6332
2.6332 1 9055
1.9055 2 1771
2.1771 10 8857
10.8857 293 7%
293.7%
68 Thread average total times 0.4957 2.0502 3.8034 2.6340 1.9065 2.1780 10.8899 292.2%
69 this vs Test A 71.2% 71.1% 118.9% 189.0% 74.4% 101.4%
70
Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 2 of 5
COMP 8005, Assignment 1 January 2011
A B C D E F G H I
71 Test C
72
file I/O loops in each Process
0 0 0 0 0
73 or Thread ...
74
Process
Process
Process
Process with no file I/O Child 1 Child 2 Child 3 Child 4 Child 5 Totals Totals vs
averages
75 Threads
76 run 1 start times 0.0012 0.0013 0.0010 0.0016 0.0023 0.0015 0.0074 238.7%
77 run 2 start times 0.0008 0.0008 0.0007 0.0019 0.0017 0.0012 0.0059 140.5%
78 run 3 start times 0.0008 0.0008 0.0007 0.0017 0.0020 0.0012 0.0060 176.5%
79 run 4 start times 0.0009 0.0008 0.0008 0.0021 0.0020 0.0013 0.0066 178.4%
80 run 5 start times 0.0006 0.0006 0.0006 0.0020 0.0018 0.0011 0.0056 60.2%
81 Process average start times 0.0009 0.0009 0.0008 0.0019 0.0020 0.0013 0.0063 132.9%
82 run 1 run times 0.0014 0.3897 3.0755 0.0030 0.0054 0.6950 3.4750 44.9%
83 run 2 run times 0.0015 0.3858 3.0408 0.0027 0.0075 0.6877 3.4383 42.5%
84 run 3 run times 0.0015 0.3829 3.0963 0.0034 0.0055 0.6979 3.4896 27.3%
85 run 4 run times 0.0016 0.3800 3.0473 0.0029 0.0077 0.6879 3.4395 30.5%
86 run 5 run times
run 5 run times 0 0014
0.0014 0 3857
0.3857 3 1460
3.1460 0 0030
0.0030 0 0060
0.0060 0 7084
0.7084 3 5421
3.5421 31 8%
31.8%
87 Process average run times 0.0015 0.3848 3.0812 0.0030 0.0064 0.6954 3.4769 34.1%
88 Process average total times 0.0023 0.3857 3.0819 0.0049 0.0084 0.6966 3.4832 34.1%
89 this vs Test A 52.7% 96.2% 97.8% 72.3% 105.8% 97.5%
90
Thread
Thread
Thread with no file I/O
Thread with no file I/O Thread 1 Thread 2
Thread 1 Thread 2 Thread 3
Thread 3 Thread 4
Thread 4 Thread 5
Thread 5 Totals Totals vs
Totals vs
averages
91 Processes
92 run 1 start times 0.0009 0.0007 0.0005 0.0005 0.0005 0.0006 0.0031 41.9%
93 run 2 start times 0.0009 0.0007 0.0007 0.0013 0.0006 0.0008 0.0042 71.2%
94 run 3 start times 0.0009 0.0007 0.0006 0.0006 0.0006 0.0007 0.0034 56.7%
95 run 4 start times 0.0009 0.0008 0.0006 0.0004 0.0010 0.0007 0.0037 56.1%
96 run 5 start times 0.0026
0 00 6 0.0029
0 00 9 0.0027
0 00 0.0007
0 000 0.0004
0 000 0.0019
0 00 9 0.0093
0 0093 166.1%
66 %
97 Thread average start times 0.0012 0.0012 0.0010 0.0007 0.0006 0.0009 0.0047 75.2%
98 run 1 run times 0.0029 0.3813 3.4891 0.3823 3.4889 1.5489 7.7445 222.9%
99 run 2 run times 0.0026 0.3962 3.6511 3.6518 0.3965 1.6196 8.0982 235.5%
100 run 3 run times 0.0023 3.4762 3.0923 3.0932 3.0964 2.5521 12.7604 365.7%
101 run 4 run times 0.3901 0.3898 3.4935 3.4949 3.4975 2.2532 11.2658 327.5%
102 run 5 run times 0.0016 0.3869 3.5822 3.5860 3.5845 2.2282 11.1412 314.5%
103 Th d i
Thread average run times 0.0799 1.0061 3.4616 2.8416 2.8128 2.0404 10.2020 293.4%%
104 Thread average total times 0.0811 1.0072 3.4627 2.8423 2.8134 2.0414 10.2068 293.0%
105 this vs Test A 11.5% 34.9% 108.2% 204.0% 109.8% 95.1%
106
Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 3 of 5
COMP 8005, Assignment 1 January 2011
A B C D E F G H I
107 Test D
108
On dedicated Internet
server with 8 processors,
100,000 100,000 100,000 100,000 100,000
and 100,000 file I/O loops
109 per Process or Thread...
per Process or Thread
110
Process
Process with 100,000 file Process
Child 1 Child 2 Child 3 Child 4 Child 5 Totals Totals vs
I/O loops averages
111 Threads
112 run 1 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%
113 run 2 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%
114 run 3 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 142.9%
115 run 4 start times 0.0002 0.0002 0.0002 0.0001 0.0002 0.0002 0.0009 128.6%
116 run 5 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%
117 Process average start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 153.1%
118 run 1 run times 0.1057 0.3595 2.4899 0.0153 0.0186 0.5978 2.9890 63.4%
119 run 2 run times 0.1210 0.3492 2.7298 0.0154 0.0193 0.6469 3.2347 34.7%
120 run 3 run times
run 3 run times 0 1283
0.1283 0 3213
0.3213 2 4767
2.4767 0 0158
0.0158 0 0182
0.0182 0 5921
0.5921 2 9603
2.9603 33 6%
33.6%
121 run 4 run times 0.0965 0.3096 2.4551 0.0135 0.0225 0.5794 2.8972 42.7%
122 run 5 run times 0.1135 0.3241 3.0586 0.0187 0.0233 0.7076 3.5382 54.2%
123 Process average run times 0.1130 0.3327 2.6420 0.0157 0.0204 0.6248 3.1239 43.2%
124 Process average total times 0.1132 0.3329 2.6422 0.0159 0.0206 0.6250 3.1249 43.2%
125 this vs Test B 672.2% 79.5% 81.4% 83.8% 72.3% 83.8%
126
Thread
Thread with 100,000 file I/O Thread
Thread 1 Thread 2 Thread 3 Thread 4 Thread 5 Totals Totals vs
loops averages
127 Processes
128 run 1 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%
129 run 2 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%
130 run 3 start times 0.0003 0.0001 0.0001 0.0001 0.0001 0.0001 0.0007 70.0%
131 run 4 start times 0.0002 0.0002 0.0001 0.0001 0.0001 0.0001 0.0007 77.8%
132 run 5 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%
133 Thread average start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 65.3%
134 run 1 run times 0.4505 0.4297 2.9049 0.4727 0.4546 0.9425 4.7124 157.7%
135 run 2 run times 0.0996 0.4342 2.9073 2.9318 2.9544 1.8655 9.3273 288.4%
136 run 3 run times 0.1680 2.9397 2.6254 2.9605 0.1171 1.7621 8.8107 297.6%
137 run 4 run times
run 4 run times 0 1074
0.1074 0 4190
0.4190 2 9005
2.9005 2 9119
2.9119 0 4400
0.4400 1 3558
1.3558 6 7788
6.7788 234 0%
234.0%
138 run 5 run times 0.1154 0.4424 2.9040 0.1209 2.9401 1.3046 6.5228 184.4%
139 Thread average run times 0.1882 0.9330 2.8484 1.8796 1.3812 1.4461 7.2304 231.5%
140 Thread average total times 0.1884 0.9331 2.8485 1.8797 1.3813 1.4462 7.2310 231.4%
141 this vs Test B 38.0% 45.5% 74.9% 71.4% 72.5% 66.4%
142
Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 4 of 5
COMP 8005, Assignment 1 January 2011
A B C D E F G H I
143 Summaries (Tests A, B, C)
144
145 average Process start time 0.0024 (sample size 75)
146 average Thread start time 0.0009 (sample size 75)
147 Thread vs Process 37.9%
148
Child / Child / Child / Child / Child /
149 Thread 1 Thread 2 Thread 3 Thread 4 Thread 5
150 average Process run time 0.0067 0.4004 3.1565 0.0076 0.0106 (sample size 15 each)
151 average Thread run time 0.4233 1.9795 3.4877 2.2892 2.4265 (sample size 15 each)
152 Thread vs Process 6324.4% 494.4% 110.5% 30067.8% #######
153
154 average Process total time 0.0079 0.4018 3.1590 0.0102 0.0149 (sample size 15 each)
155 average Thread total time 0.4244 1.9805 3.4885 2.2899 2.4275 (sample size 15 each)
156 Thread vs Process 5390.6% 492.9% 110.4% 22464.7% #######
157
158 median Process run time 0.0018 0.3959 3.1460 0.0034 0.0075 (sample size 15 each)
159 median Thread run time 0.2476 0.7985 3.5024 3.0932 3.0997 (sample size 15 each)
160 Thread vs Process
Thread vs Process ####### 201 7%
201.7% 111 3% 90976
111.3% 90976.5%
5% #######
161
variance in Process run
162 times 0.0001 0.0003 0.0064 0.0000 0.0001 (sample size 15 each)
163 variance in Thread run times 0.6038 2.6307 0.1045 2.8874 2.3663 (sample size 15 each)
164 Thread vs Process ####### ####### 1638.5% ######## #######
165
166 median Process start time 0.0009 0.0009 0.0010 0.0019 0.0023 (sample size 15 each)
167 median Thread start time 0.0009 0.0008 0.0006 0.0006 0.0008 (sample size 15 each)
168 Thread vs Process 100.0% 88.9% 60.0% 31.6% 34.8%
169
variance in Process start
170 times 0.000001 ####### 0.000012 0.000003 ####### (sample size 15 each)
variance in Thread start
i i Th d t t
171 times 0.000000 ####### 0.000000 0.000000 ####### (sample size 15 each)
172 Thread vs Process 52.6% 29.5% 2.4% 4.5% 2.1%
173
174 Notes:
175 Numbers above are in seconds, shown to 4 decimal places.
176 Original timings were to 6 decimal point precision: thus some rounding appears.
Prime number Child / Child / Child / Child / Child /
177 decompositions calculated: Thread 1 Thread 2 Thread 3 Thread 4 Thread 5
992923727 = 2050700031 = 883993838 = 100939437 =
998 = 2 * 499 107 * 3 * 3 * 3 * 2 * 7 * 13 * 3 * 3 * 139 *
9279661 75951853 157 * 30937 80687
178
Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 5 of 5
1 /*********************************************************************
2 * Author and Copyright (c) A. Abdulla, January 2001
3 * Original program name: pipe_nonblocking.c
4 * Modified program name: processes.c
5 * Modified by: Arthur (Wesley) Kenzie (BCIT Student ID A00242330)
6 * Modified date: January 28, 2011
7 * Latest version: 1.07a
8 * Description: this program is adapted to demonstrate 3‐9 processes
9 * to be compared to 3‐9 threads in the separate threads.c program
10 * for Assignment 1 in COMP 8005
11 * thanks to rosettacode.org/Prime_decomposition#C
12 * uses the GMP (GNU Multiple Precision Library for the computations
13 **********************************************************************/
14 /********************************************************************
15 * compile as follows:
16 * gcc ‐Wall ‐o a1p processes.c primedecompose.c ‐lgmp ‐lm
17 * to link in gmp and math libraries
18 *********************************************************************/
19 /********************************************************************
20 * run as follows:
21 * ./a1p [‐‐debug] [‐‐skipfileio] [‐‐skipcpu] [‐‐ioloops=x] 1 2 3 4 5 6 7 8 9
22 * where 1‐9 are 3‐9 integer numbers
23 * and ‐‐ioloops=x will only be used if ‐‐skipfileio is not included
24 * and x value in ‐‐ioloops= parameter is 10^x loops
25 *********************************************************************/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include </usr/include/gmp.h>
30 #include "primedecompose.h"
31 #include <fcntl.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <math.h>
35 #include <sys/time.h>
36
37 #define MSGSIZE 16
38 #define MAX_FACTORS 1024
39 #define BASE10 10
40 #define MINNUMS 3
41 #define MAXNUMS 9
42 #define BCOMM 0 // communicate through pipes or not
43
44 /*‐‐‐‐‐‐ Function prototypes ‐‐‐‐‐‐‐‐‐‐*/
45 int parent (int p[], const uint);
46 void child (int p[], const uint, const uint, const long unsigned int, const double);
47 int calc (char *);
48 void fatal (char *);
49
50 /*‐‐‐‐‐‐‐ globals ‐‐‐‐‐‐‐‐‐‐‐‐‐*/
51 int bdebug = 0; // debug mode or not (default no)
52 int bfileio = 1; // do file i/o in thread (default yes)
53 int bcpu = 1; // do cpu computations in thread (default yes)
54 uint ioloops = 1000; // number of file io loops to do in thread (default 10^3)
55 char *msg1 = "Hello World";
56 char *msg2 = "Goodbye World";
57 char errstr[255];
58 int pint;
59 mpz_t dest[MAX_FACTORS]; // must be large enough to hold all the factors!
60
61 int main(int argc, char **argv)
62 {
63 struct timeval ttp;
64 double tt1, tt2, tt3;
65 gettimeofday(&ttp, NULL);
66 tt1 = ttp.tv_sec+(ttp.tv_usec/1000000.0);
67 long unsigned int linum[argc]; // array of integers entered on command line
68 uint n, processcount, childnum;
69 int pfd[argc][2];
70 char * debug_parm = "‐‐debug";
71 char * skipfileio_parm = "‐‐skipfileio";
72 char * skipcpu_parm = "‐‐skipcpu";
73 char * ioloops_parm = "‐‐ioloops=";
74 uint ioloops_len = strlen(ioloops_parm);
75
76 if((argc‐1 < MINNUMS) || (argc‐1 > MAXNUMS))
77 {
78 printf("Usage: %s <%i‐%i integers (>0 and <2B) to be factored>\n", argv[0], MINNUMS, MAXNUMS);
79 exit(1);
80 }
81 if ( bdebug )
82 {
83 printf("debug: %i parameters\n", (argc‐1));
84 }
85 //
86 processcount = 0;
87 for ( n=1; n<argc; n++ )
88 {
89 // ‐‐debug parameter (anywhere) will turn on debugging mode
90 if ( strcmp((char *)argv[n], debug_parm) == 0 )
91 {
92 bdebug = 1;
93 continue;
94 }
95 // ‐‐skipfileio parameter (anywhere) will skip file i/o in threads
96 if ( strcmp((char *)argv[n], skipfileio_parm) == 0 )
97 {
98 bfileio = 0;
99 continue;
100 }
101 // ‐‐skipcpu parameter (anywhere) will skip cpu work in threads
102 if ( strcmp((char *)argv[n], skipcpu_parm) == 0 )
103 {
104 bcpu = 0;
105 continue;
106 }
107 // ‐‐ioloops= parameter (anywhere) will specify number of file i/o loops in threads
108 // where ‐‐ioloops=3 will do 1,000 loops
109 // ‐‐ioloops=5 will do 100,000 loops
110 if ( strncmp((char *)argv[n], ioloops_parm, ioloops_len) == 0 )
111 {
112 ioloops = (int)pow((double)10, (double)strtol(argv[n]+ioloops_len, NULL, BASE10));
113 continue;
114 }
115 processcount++;
116 linum[processcount] = strtol(argv[n], NULL, BASE10);
117 if ( linum[processcount] <= 0 )
118 {
119 printf("Usage: %s <%i‐%i integers (>0 and <2B) to be factored>\n", argv[0], MINNUMS, MAXNUMS);
120 exit(1);
121 }
122 }
123 if ( bdebug )
124 {
125 printf("debug: %i parameters\n", (argc‐1));
126 for ( n=1; n<=processcount; n++ )
127 {
128 printf("debug: integer %i = %li\n", n, linum[n]);
129 }
130 printf("\n");
131 }
132 //
133 for ( childnum=1; childnum<=processcount; childnum++ )
134 {
135 /*‐‐‐‐‐ Open the pipe(s) between child and parent ‐‐‐‐‐‐‐‐‐‐‐*/
136 sprintf(errstr, "pipe %i call", childnum);
137 if (pipe(pfd[childnum]) < 0)
138 {
139 fatal (errstr);
140 }
141 /*‐‐‐‐ Set the O_NDELAY flag(s) for p[0] ‐‐‐‐‐‐‐‐‐‐‐*/
142 sprintf(errstr, "fcntl %i call", childnum);
143 if (fcntl (pfd[childnum][0], F_SETFL, O_NDELAY) < 0)
144 {
145 fatal (errstr);
146 }
147 }
148 /*‐‐‐‐‐‐‐‐ fork (each child) ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/
149 for ( childnum=1; childnum<=processcount; childnum++ )
150 {
151 sprintf(errstr, "fork %i call", childnum);
152 if ( bdebug )
153 {
154 printf( "debug: child %i about to start with %li\n", childnum, linum[childnum] );
155 }
156 gettimeofday(&ttp, NULL);
157 tt2 = ttp.tv_sec+(ttp.tv_usec/1000000.0);
158 switch(fork())
159 {
160 case ‐1: /* error */
161 fatal (errstr);
162 case 0: /* It's the child */
163 child (pfd[childnum], BCOMM, childnum, linum[childnum], tt2);
164 printf("child %i finished\n", childnum);
165 default: /* parent */
166 pint = parent (pfd[childnum], BCOMM);
167 //printf("parent finished child %i with %i\n", childnum, pint);
168 }
169 }
170 gettimeofday(&ttp, NULL);
171 tt3 = ttp.tv_sec+(ttp.tv_usec/1000000.0);
172 if ( bdebug )
173 {
174 printf("debug: program finished after %.4lf seconds\n", tt3‐tt1);
175 }
176 exit(0);
177 }
178
179 /*‐‐‐‐‐‐‐ Parent process function ‐‐‐‐‐‐‐*/
180 // parameter int p[2] is array of pipes to and from child process
181 // p[0] is read descriptor of pipe from child
182 // p[1] is write descriptor of pipe to child
183 // parameter const uint bcomm is boolean whether to read messages being sent from child process to parent
184 // returns int 0 if finished successfully
185 // returns int <> 0 if finished unsuccessfully
186 int parent (int p[2], const uint bcomm)
187 {
188 int nread;
189 char buf[MSGSIZE];
190
191 // if not bcomm then nothing happens in this function
192 if ( bcomm )
193 {
194 close (p[1]); /* close the write descriptor */
195 for (;;)
196 {
197 switch (nread = read(p[0], buf, MSGSIZE))
198 {
199 case ‐1:
200 case 0:
201 if ( bdebug )
202 {
203 printf ("debug: (pipe to/with child empty)\n");
204 }
205 sleep(0);
206 break;
207 default:
208 if (strcmp (buf, msg2) == 0)
209 {
210 printf ("End of conversation with child\n");
211 return(0);
212 }
213 else
214 {
215 printf ("MSG = %s\n", buf);
216 }
217 }
218 }
219 }
220 return(0);
221 }
222
223 /*‐‐‐‐‐‐ Child process function ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/
224 // parameter int p[2] is array of pipes to and from parent process
225 // p[0] is read descriptor of pipe from parent
226 // p[1] is write descriptor of pipe to parent
227 // parameter const uint bcomm is boolean to indicate whether child should communicate with parent over pipes
228 // parameter uint childnum is (arbitrary) number of this child process
229 // parameter num is long long unsigned integer to be decomposed by this child process
230 // parameter dtime is double holding time at start of fork which created this child process
231 // returns void
232 // child process kills itself with exit(0) when done
233 void child (int p[2], const uint bcomm, const uint childnum, const long unsigned int num, const double
dtime)
234 {
235 struct timeval tp;
236 double t1, t2;
237 gettimeofday(&tp, NULL);
238 t1 = tp.tv_sec+(tp.tv_usec/1000000.0);
239 printf("child %i started in %.4lf seconds with: %li\n", childnum, t1‐dtime, num);
240 int icalc;
241 FILE *fp;
242
243 close (p[0]); /* close the read descriptor */
244
245 char filename[255];
246 char rbuffer[2];
247 char wbuffer[255];
248 char s[255];
249 printf("child %i result: ", childnum);
250 sprintf(s, "%li", num); // this is integer that gets passed to calc()
251 if ( bdebug )
252 {
253 printf("debug: child %i string %s\n", childnum, s);
254 }
255
256 // do some cpu computation stuff on the integer passed in
257 if ( bcpu )
258 {
259 printf("child %i: ", childnum);
260 icalc = calc(s);
261 printf("\n");
262 }
263
264 // now do some file i/o stuff
265 if ( bfileio )
266 {
267 sprintf(filename, "child%i.txt", childnum);
268 fp = fopen(filename, "w");
269 if ( fp == NULL )
270 {
271 // error
272 printf("error: child %i file error\n", childnum);
273 }
274 else
275 {
276 if ( bdebug )
277 {
278 printf("debug: child %i file %s initialized\n", childnum, filename);
279 }
280 for ( icalc=0; icalc<ioloops; icalc++ )
281 {
282 fputs(wbuffer, fp);
283 fgets(rbuffer, 2, fp);
284 }
285 fclose(fp);
286 }
287 }
288
289 if ( bcomm )
290 {
291 /*‐‐‐ Send final message ‐‐‐‐‐‐‐‐‐‐‐‐*/
292 write (p[1], msg2, MSGSIZE);
293 }
294 gettimeofday(&tp, NULL);
295 t2 = tp.tv_sec+(tp.tv_usec/1000000.0);
296 printf("child %i finished after %.4lf seconds\n", childnum, t2‐t1);
297 exit(0);
298 }
299
300 /* calc function */
301 // thanks to rosettacode.org/Prime_decomposition#C
302 // January 2011
303 int calc(char * s)
304 {
305 mpz_t n;
306 int i, l;
307 mpz_init_set_str(n, s, 10);
308 l = decompose(n, dest);
309
310 for(i=0; i < l; i++)
311 {
312 gmp_printf("%s%Zd", i?" * ":"", dest[i]);
313 mpz_clear(dest[i]);
314 }
315 return EXIT_SUCCESS;
316 }
317
318 /*‐‐‐‐‐‐‐‐‐‐ Error function ‐‐‐‐‐‐*/
319 // returns void
320 // parameter char * is message to be printed before program aborts
321 void fatal (char *s)
322 {
323 perror (s); /* print error msg and die */
324 exit(1);
325 }
1 /*******************************************************************
2 * Author and Copyright (c) A. Abdulla, January 2001
3 * Original program name: multi.c
4 * Modified program name: threads.c
5 * Modified by: Arthur (Wesley) Kenzie (BCIT Student ID A00242330)
6 * Modified date: January 28, 2011
7 * Latest version: 1.02f
8 * Description: this program is adapted to demonstrate 3‐9 threads
9 * to be compared to 3‐9 processes in the separate processes.c program
10 * for Assignment 1 in COMP 8005
11 * thanks to rosettacode.org/Prime_decomposition#C
12 * uses the GMP (GNU Multiple Precision Library for the computations
13 *********************************************************************/
14 /********************************************************************
15 * compile as follows:
16 * gcc ‐Wall ‐o a1t threads.c primedecompose.c ‐lgmp ‐lpthread ‐lm
17 * to link in gmp, pthread and math libraries
18 *********************************************************************/
19 /********************************************************************
20 * run as follows:
21 * ./a1t [‐‐debug] [‐‐skipfileio] [‐‐skipcpu] [‐‐ioloops=x] 1 2 3 4 5 6 7 8 9
22 * where 1‐9 are 3‐9 integer numbers
23 * and ‐‐ioloops=x will only be used if ‐‐skipfileio is not included
24 * and x value in ‐‐ioloops= parameter is 10^x loops
25 *********************************************************************/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include </usr/include/gmp.h>
30 #include "primedecompose.h"
31 #include <fcntl.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <math.h>
35 #include <sys/time.h>
36 #include <pthread.h>
37
38 #define _REENTRANT
39 #define DCE_COMPAT
40 #define MAX_FACTORS 1024
41 #define BASE10 10
42 #define MINNUMS 3 // min number of threads
43 #define MAXNUMS 9 // max number of threads
44
45 /*‐‐‐‐‐‐ Function prototypes ‐‐‐‐‐‐‐‐‐‐*/
46 void * calcplusio (void *);
47 void fatal (char *);
48
49 /*‐‐‐‐‐‐‐‐‐‐‐‐ Mutex Variables ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/
50 pthread_mutex_t decomposeLock = PTHREAD_MUTEX_INITIALIZER;
51
52 /*‐‐‐‐‐‐‐ globals ‐‐‐‐‐‐‐‐‐‐‐‐‐*/
53 int bdebug = 0; // debug mode or not (default no)
54 int bfileio = 1; // do file i/o in thread (default yes)
55 int bcpu = 1; // do cpu computations in thread (default yes)
56 uint ioloops = 1000; // number of file io loops to do in thread (default 10^3)
57 struct thread_data {
58 int threadnum; // thread number
59 long int linum; // long int to be decomposed
60 int bdebug; // is debug enabled?
61 double dtime; // time at start of pthread_create()
62 int bfileio; // do file I/O in thread?
63 int bcpu; // do cpu computations in thread?
64 uint iloops; // number of file I/O loops in thread
65 };
66 struct thread_data thread_data_array[MAXNUMS]; // passed to each thread
67
68 int main(int argc, char **argv)
69 {
70 struct timeval ttp;
71 double tt1, tt2, tt3;
72 gettimeofday(&ttp, NULL);
73 tt1 = ttp.tv_sec+(ttp.tv_usec/1000000.0); // program start time
74 char errstr[255];
75 long unsigned int linum[argc]; // array of integers entered on command line
76 uint n, threadcount;
77 pthread_t thread[argc];
78 uint threadnum;
79 int pint; // pthread_create() result
80 char * debug_parm = "‐‐debug";
81 char * skipfileio_parm = "‐‐skipfileio";
82 char * skipcpu_parm = "‐‐skipcpu";
83 char * ioloops_parm = "‐‐ioloops=";
84 uint ioloops_len = strlen(ioloops_parm);
85
86 if((argc‐1 < MINNUMS) || (argc‐1 > MAXNUMS))
87 {
88 printf("Usage: %s <%i‐%i integers (>0 and <2B) to be factored>\n", argv[0], MINNUMS, MAXNUMS);
89 exit(1);
90 }
91 //
92 threadcount = 0;
93 for ( n=1; n<argc; n++ )
94 {
95 // ‐‐debug parameter (anywhere) will turn on debugging mode
96 if ( strcmp((char *)argv[n], debug_parm) == 0 )
97 {
98 bdebug = 1;
99 continue;
100 }
101 // ‐‐skipfileio parameter (anywhere) will skip file i/o in threads
102 if ( strcmp((char *)argv[n], skipfileio_parm) == 0 )
103 {
104 bfileio = 0;
105 continue;
106 }
107 // ‐‐skipcpu parameter (anywhere) will skip cpu work in threads
108 if ( strcmp((char *)argv[n], skipcpu_parm) == 0 )
109 {
110 bcpu = 0;
111 continue;
112 }
113 // ‐‐ioloops= parameter (anywhere) will specify number of file i/o loops in threads
114 // where ‐‐ioloops=3 will do 1,000 loops
115 // ‐‐ioloops=5 will do 100,000 loops
116 if ( strncmp((char *)argv[n], ioloops_parm, ioloops_len) == 0 )
117 {
118 ioloops = (int)pow((double)10, (double)strtol(argv[n]+ioloops_len, NULL, BASE10));
119 continue;
120 }
121 threadcount++;
122 linum[threadcount] = strtol(argv[n], NULL, BASE10);
123 if ( linum[threadcount] <= 0 )
124 {
125 printf("Usage: %s <%i‐%i integers (>0 and <2B) to be factored>\n", argv[0], MINNUMS, MAXNUMS);
126 exit(1);
127 }
128 }
129 if ( bdebug )
130 {
131 printf("debug: %i parameters\n", (argc‐1));
132 for ( n=1; n<=threadcount; n++ )
133 {
134 printf("debug: integer %i = %li\n", n, linum[n]);
135 }
136 printf("\n");
137 }
138
139 /* ‐‐‐‐‐‐‐‐‐ create each thread ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ */
140 for ( threadnum=1; threadnum<=threadcount; threadnum++ )
141 {
142 sprintf( errstr, "error: pthread_create %i call", threadnum );
143 if ( bdebug )
144 {
145 printf( "debug: thread %i about to start with %li\n", threadnum, linum[threadnum] );
146 }
147 thread_data_array[threadnum].threadnum = threadnum;
148 thread_data_array[threadnum].linum = linum[threadnum];
149 thread_data_array[threadnum].bdebug = bdebug;
150 thread_data_array[threadnum].bfileio = bfileio;
151 thread_data_array[threadnum].iloops = ioloops;
152 thread_data_array[threadnum].bcpu = bcpu;
153 gettimeofday(&ttp, NULL);
154 tt2 = ttp.tv_sec+(ttp.tv_usec/1000000.0);
155 thread_data_array[threadnum].dtime = tt2;
156 pint = pthread_create( &thread[threadnum], NULL, calcplusio, (void *) &thread_data_array[threadnum]
);
157 if ( pint )
158 {
159 fatal( errstr );
160 }
161 }
162
163 gettimeofday(&ttp, NULL);
164 tt3 = ttp.tv_sec+(ttp.tv_usec/1000000.0);
165 if ( bdebug )
166 {
167 printf("debug: program finished after %.4lf seconds\n", tt3‐tt1);
168 }
169 pthread_exit(0); // will wait for all threads to finish before exiting
170 }
171
172 /* calcplusio function */
173 // thanks to rosettacode.org/Prime_decomposition#C
174 // based on calc() function
175 // returns void (since this is a thread(ed) function)
176 // parameter td is thread_array struct with thread data
177 // January 2011
178 void * calcplusio(void * td)
179 {
180 struct timeval tp;
181 double t1, t2;
182 gettimeofday(&tp, NULL);
183 t1 = tp.tv_sec+(tp.tv_usec/1000000.0);
184 struct thread_data *parm;
185 parm = (struct thread_data *) td;
186 printf("thread %i started in %.4lf seconds with: %li\n", parm‐>threadnum, t1‐parm‐>dtime, parm‐>linum );
187
188 mpz_t n;
189 int i, l;
190 mpz_t dest[MAX_FACTORS]; // must be large enough to hold all the factors!
191 FILE *fp;
192 char rbuffer[2];
193 char wbuffer[255];
194 char filename[255];
195 char s[255];
196 sprintf(s, "%li", parm‐>linum);
197 if ( parm‐>bdebug )
198 {
199 printf("debug: thread %i string %s\n", parm‐>threadnum, s);
200 }
201
202 // do some cpu computation stuff on the integer passed in
203 if ( parm‐>bcpu )
204 {
205 mpz_init_set_str(n, s, 10);
206 pthread_mutex_lock( &decomposeLock );
207 l = decompose(n, dest);
208 pthread_mutex_unlock( &decomposeLock );
209 printf("thread %i: ", parm‐>threadnum);
210 for( i=0; i < l; i++ )
211 {
212 gmp_printf("%s%Zd", i?" * ":"", dest[i]);
213 mpz_clear(dest[i]);
214 }
215 printf("\n");
216 }
217
218 // now do some file i/o stuff
219 if ( parm‐>bfileio )
220 {
221 sprintf(filename, "thread%i.txt", parm‐>threadnum);
222 sprintf(wbuffer, "%li", parm‐>linum); // write buffer
223 fp = fopen(filename, "w");
224 if ( fp == NULL )
225 {
226 // error
227 printf("error: thread %i file %s could not be created\n", parm‐>threadnum, filename);
228 }
229 else
230 {
231 if ( bdebug )
232 {
233 printf("\ndebug: thread %i file %s initialized\n", parm‐>threadnum, filename);
234 }
235 for ( i=0; i<(parm‐>iloops); i++ )
236 {
237 //pthread_mutex_lock( &fputsLock );
238 fputs(wbuffer, fp);
239 //pthread_mutex_unlock( &fputsLock );
240 //pthread_mutex_lock( &fgetsLock );
241 fgets(rbuffer, 2, fp);
242 //pthread_mutex_unlock( &fgetsLock );
243 }
244 fclose(fp);
245 }
246 }
247 gettimeofday(&tp, NULL);
248 t2 = tp.tv_sec+(tp.tv_usec/1000000.0);
249 printf("thread %i finished after %.4lf seconds\n", parm‐>threadnum, t2‐t1);
250
251 pthread_exit((void *) NULL);
252 }
253
254 /*‐‐‐‐‐‐‐‐‐‐ Error function ‐‐‐‐‐‐*/
255 // returns void
256 // parameter char * is message to be printed before program aborts
257 void fatal (char *s)
258 {
259 perror (s); /* print error msg and die */
260 exit(1);
261 }