Top Banner

Click here to load reader

37

BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

Jul 27, 2015

Download

Documents

Wesley Kenzie

This was an assignment I did for my COMP 8005 Network Security and Application Development course at BCIT. I wrote 2 programs in C, one using multiple threads, and the other using multiple processes, to perform identical tasks. The start up times and run times for each of the tasks was measured and tabulated, with a total sample size of 100 measurements for each program.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 1 of 23

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. Introduction ............................................................................................ page 2 Methodology ............................................................................................ page 2 Test A (On Xubuntu Desktop VM) ................................................................. page 4 Test B (Same as Test A, but with 1000x more file I/O) ................................... page 9 Test C (Same as Test A, but with no file I/O) ................................................. page 12 Test D (Same as Test B, but on dedicated server running Ubuntu Server) ......... page 15 Summaries and Conclusions ..................................................................... page 18 Appendix .................................................................................................. page 19 Bibliography ............................................................................................. page 22 Credits ...................................................................................................... page 23

Page 2: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 2 of 23

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.

Page 3: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 3 of 23

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.

Page 4: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 4 of 23

Test A (On Xubuntu Desktop VM) 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:

Page 5: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 5 of 23

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: ./a1t 998 992923727 2050700031 883993838 100939437 --ioloops=1

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.

Page 6: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 6 of 23

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.

Thread with 10 file I/O loops 

Thread 1 

Thread 2 

Thread 3 

Thread 4 

Thread 5 

Thread averages 

Totals 

run 1 start times  0.0021  0.0011  0.0005  0.0009 0.0011  0.0011  0.0057

run 2 start times  0.0010  0.0008  0.0006  0.0004 0.0011  0.0008  0.0039

run 3 start times  0.0009  0.0009  0.0006  0.0004 0.0015  0.0009  0.0043

run 4 start times  0.0010  0.0009  0.0007  0.0006 0.0021  0.0011  0.0053

run 5 start times  0.0009  0.0007  0.0006  0.0013 0.0005  0.0008  0.0040

Thread average start times  0.0012  0.0009  0.0006  0.0007 0.0013  0.0009  0.0046

run 1 run times  3.0784  3.4788  3.0804  3.0858 3.0845  3.1616  15.8079

run 2 run times  0.0030  3.4893  3.1106  0.0045 3.1092  1.9433  9.7166

run 3 run times  0.0032  3.4758  3.0950  3.4775 3.0997  2.6302  13.1512

run 4 run times  0.0040  3.5864  3.2055  0.0093 0.0080  1.3626  6.8132

run 5 run times  0.3874  0.3855  3.5024  0.3860 3.5050  1.6333  8.1663

Thread average run times  0.6952  2.8832  3.1988  1.3926 2.5613  2.1462  10.7310

Thread average total times  0.6964  2.8840  3.1994  1.3933 2.5625  2.1471  10.7357

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.

Page 7: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 7 of 23

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.

Page 8: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 8 of 23

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 loops 

Child 1  Child 2  Child 3  Child 4  Child 5 Process averages 

Totals 

run 1 start times  0.0008  0.0009 0.0010  0.0017 0.0006  0.0010  0.0050

run 2 start times  0.0010  0.0018 0.0038  0.0053 0.0024  0.0029  0.0143

run 3 start times  0.0010  0.0012 0.0010  0.0016 0.0017  0.0013  0.0065

run 4 start times  0.0011  0.0013 0.0012  0.0017 0.0024  0.0015  0.0077

run 5 start times  0.0035  0.0043 0.0015  0.0023 0.0021  0.0027  0.0137

Process average start times  0.0015  0.0019 0.0017  0.0025 0.0018  0.0019  0.0094

run 1 run times  0.0065  0.4175 3.1952  0.0028 0.0056  0.7255  3.6276

run 2 run times  0.0031  0.4010 3.1160  0.0032 0.0062  0.7059  3.5295

run 3 run times  0.0016  0.3959 3.1833  0.0032 0.0053  0.7179  3.5893

run 4 run times  0.0018  0.3921 3.1176  0.0041 0.0081  0.7047  3.5237

run 5 run times  0.0018  0.3895 3.1341  0.0077 0.0052  0.7077  3.5383

Process average run times  0.0030  0.3992 3.1492  0.0042 0.0061  0.7123  3.5617

Process average total times  0.0044  0.4011 3.1509  0.0067 0.0079  0.7142  3.5711

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.

Page 9: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 9 of 23

Test B (Same as Test A, but with 1000x more file I/O) 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: ./a1p 998 992923727 2050700031 883993838 100939437 --ioloops=5 This will generate 100,000 file input/output operations, rather than the 10 done in Test A.

Page 10: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 10 of 23

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.

Thread with 100,000 file I/O loops 

Thread 1 Thread 

2 Thread 

3 Thread 4  Thread 5 

Thread averages 

Totals 

run 1 start times  0.0011  0.0009 0.0007  0.0006 0.0004  0.0007  0.0037

run 2 start times  0.0010  0.0008 0.0006  0.0006 0.0011  0.0008  0.0041

run 3 start times  0.0008  0.0008 0.0007  0.0005 0.0022  0.0010  0.0050

run 4 start times  0.0005  0.0008 0.0005  0.0010 0.0008  0.0007  0.0036

run 5 start times  0.0011  0.0008 0.0007  0.0014 0.0006  0.0009  0.0046

Thread average start times  0.0009  0.0008 0.0006  0.0008 0.0010  0.0008  0.0042

run 1 run times  0.5144  0.7985 3.8853  0.5749 0.5576  1.2661  6.3307

run 2 run times  0.7624  0.7624 4.0316  4.0262 4.0591  2.7283  13.6417

run 3 run times  0.2476  0.7075 4.0049  4.0122 4.0230  2.5990  12.9952

run 4 run times  0.5224  3.9509 3.5664  0.5247 0.5067  1.8142  9.0711

run 5 run times  0.4274  4.0277 3.5258  4.0281 0.3810  2.4780  12.3900

Thread average run times  0.4948  2.0494 3.8028  2.6332 1.9055  2.1771  10.8857

Thread average total times  0.4957  2.0502 3.8034  2.6340 1.9065  2.1780  10.8899

this vs Test A  71.2%  71.1% 118.9%  189.0% 74.4%  101.4% 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.

Page 11: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 11 of 23

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 file I/O loops 

Child 1  Child 2  Child 3  Child 4  Child 5 Process averages 

Totals 

run 1 start times  0.0017  0.0013 0.0131 0.0038 0.0101 0.0060  0.0300

run 2 start times  0.0019  0.0029 0.0082 0.0072 0.0113 0.0063  0.0315

run 3 start times  0.0009  0.0007 0.0029 0.0026 0.0027 0.0020  0.0098

run 4 start times  0.0007  0.0006 0.0014 0.0018 0.0100 0.0029  0.0145

run 5 start times  0.0008  0.0008 0.0006 0.0014 0.0112 0.0030  0.0148

Process average start times  0.0012  0.0013 0.0052 0.0034 0.0091 0.0040  0.0201

run 1 run times  0.0214  0.4396 3.3315 0.0153 0.0259 0.7667  3.8337

run 2 run times  0.0218  0.4153 3.2627 0.0248 0.0201 0.7489  3.7447

run 3 run times  0.0145  0.4213 3.2047 0.0170 0.0270 0.7369  3.6845

run 4 run times  0.0102  0.4120 3.1892 0.0109 0.0123 0.7269  3.6346

run 5 run times  0.0103  0.3982 3.2068 0.0102 0.0118 0.7275  3.6373

Process average run times  0.0156  0.4173 3.2390 0.0156 0.0194 0.7414  3.7070

Process average total times  0.0168  0.4185 3.2442 0.0190 0.0285 0.7454  3.7271

this vs Test A  379.3%  104.3% 103.0% 282.7% 359.6% 104.4% 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.

Page 12: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 12 of 23

Test C (Same as Test A, but with no file I/O) 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: ./a1p 998 992923727 2050700031 883993838 100939437 --skipfileio

Page 13: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 13 of 23

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.

Thread with no file I/O  Thread 1 Thread 

2 Thread 

3 Thread 4  Thread 5 

Thread averages 

Totals 

run 1 start times  0.0009  0.0007 0.0005  0.0005 0.0005  0.0006  0.0031

run 2 start times  0.0009  0.0007 0.0007  0.0013 0.0006  0.0008  0.0042

run 3 start times  0.0009  0.0007 0.0006  0.0006 0.0006  0.0007  0.0034

run 4 start times  0.0009  0.0008 0.0006  0.0004 0.0010  0.0007  0.0037

run 5 start times  0.0026  0.0029 0.0027  0.0007 0.0004  0.0019  0.0093

Thread average start times  0.0012  0.0012 0.0010  0.0007 0.0006  0.0009  0.0047

run 1 run times  0.0029  0.3813 3.4891  0.3823 3.4889  1.5489  7.7445

run 2 run times  0.0026  0.3962 3.6511  3.6518 0.3965  1.6196  8.0982

run 3 run times  0.0023  3.4762 3.0923  3.0932 3.0964  2.5521  12.7604

run 4 run times  0.3901  0.3898 3.4935  3.4949 3.4975  2.2532  11.2658

run 5 run times  0.0016  0.3869 3.5822  3.5860 3.5845  2.2282  11.1412

Thread average run times  0.0799  1.0061 3.4616  2.8416 2.8128  2.0404  10.2020

Thread average total times  0.0811  1.0072 3.4627  2.8423 2.8134  2.0414  10.2068

this vs Test A  11.5%  34.9% 108.2%  204.0% 109.8%  95.1% 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.

Page 14: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 14 of 23

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 with no file I/O  Child 1  Child 2  Child 3  Child 4  Child 5 Process averages 

Totals 

run 1 start times  0.0012  0.0013 0.0010 0.0016 0.0023 0.0015  0.0074

run 2 start times  0.0008  0.0008 0.0007 0.0019 0.0017 0.0012  0.0059

run 3 start times  0.0008  0.0008 0.0007 0.0017 0.0020 0.0012  0.0060

run 4 start times  0.0009  0.0008 0.0008 0.0021 0.0020 0.0013  0.0066

run 5 start times  0.0006  0.0006 0.0006 0.0020 0.0018 0.0011  0.0056

Process average start times  0.0009  0.0009 0.0008 0.0019 0.0020 0.0013  0.0063

run 1 run times  0.0014  0.3897 3.0755 0.0030 0.0054 0.6950  3.4750

run 2 run times  0.0015  0.3858 3.0408 0.0027 0.0075 0.6877  3.4383

run 3 run times  0.0015  0.3829 3.0963 0.0034 0.0055 0.6979  3.4896

run 4 run times  0.0016  0.3800 3.0473 0.0029 0.0077 0.6879  3.4395

run 5 run times  0.0014  0.3857 3.1460 0.0030 0.0060 0.7084  3.5421

Process average run times  0.0015  0.3848 3.0812 0.0030 0.0064 0.6954  3.4769

Process average total times  0.0023  0.3857 3.0819 0.0049 0.0084 0.6966  3.4832

this vs Test A  52.7%  96.2% 97.8% 72.3% 105.8% 97.5% 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.

Page 15: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 15 of 23

Test D (Same as Test B, but on dedicated server running Ubuntu Server) 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: ./a1p 998 992923727 2050700031 883993838 100939437 --ioloops=5

Page 16: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 16 of 23

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.

Thread with 100,000 file I/O loops 

Thread 1 Thread 

2 Thread 

3 Thread 4  Thread 5 

Thread averages 

Totals 

run 1 start times  0.0002  0.0001 0.0001 0.0001 0.0001 0.0001  0.0006

run 2 start times  0.0002  0.0001 0.0001 0.0001 0.0001 0.0001  0.0006

run 3 start times  0.0003  0.0001 0.0001 0.0001 0.0001 0.0001  0.0007

run 4 start times  0.0002  0.0002 0.0001 0.0001 0.0001 0.0001  0.0007

run 5 start times  0.0002  0.0001 0.0001 0.0001 0.0001 0.0001  0.0006

Thread average start times  0.0002  0.0001 0.0001 0.0001 0.0001 0.0001  0.0006

run 1 run times  0.4505  0.4297 2.9049 0.4727 0.4546 0.9425  4.7124

run 2 run times  0.0996  0.4342 2.9073 2.9318 2.9544 1.8655  9.3273

run 3 run times  0.1680  2.9397 2.6254 2.9605 0.1171 1.7621  8.8107

run 4 run times  0.1074  0.4190 2.9005 2.9119 0.4400 1.3558  6.7788

run 5 run times  0.1154  0.4424 2.9040 0.1209 2.9401 1.3046  6.5228

Thread average run times  0.1882  0.9330 2.8484 1.8796 1.3812 1.4461  7.2304

Thread average total times  0.1884  0.9331 2.8485 1.8797 1.3813 1.4462  7.2310

this vs Test B  38.0%  45.5% 74.9% 71.4% 72.5% 66.4% 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.

Page 17: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 17 of 23

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 file I/O loops 

Child 1  Child 2  Child 3  Child 4  Child 5 Process averages 

Totals 

run 1 start times  0.0002  0.0002 0.0002 0.0002 0.0002 0.0002  0.0010

run 2 start times  0.0002  0.0002 0.0002 0.0002 0.0002 0.0002  0.0010

run 3 start times  0.0002  0.0002 0.0002 0.0002 0.0002 0.0002  0.0010

run 4 start times  0.0002  0.0002 0.0002 0.0001 0.0002 0.0002  0.0009

run 5 start times  0.0002  0.0002 0.0002 0.0002 0.0002 0.0002  0.0010

Process average start times  0.0002  0.0002 0.0002 0.0002 0.0002 0.0002  0.0010

run 1 run times  0.1057  0.3595 2.4899 0.0153 0.0186 0.5978  2.9890

run 2 run times  0.1210  0.3492 2.7298 0.0154 0.0193 0.6469  3.2347

run 3 run times  0.1283  0.3213 2.4767 0.0158 0.0182 0.5921  2.9603

run 4 run times  0.0965  0.3096 2.4551 0.0135 0.0225 0.5794  2.8972

run 5 run times  0.1135  0.3241 3.0586 0.0187 0.0233 0.7076  3.5382

Process average run times  0.1130  0.3327 2.6420 0.0157 0.0204 0.6248  3.1239

Process average total times  0.1132  0.3329 2.6422 0.0159 0.0206 0.6250  3.1249

this vs Test B  672.2%  79.5% 81.4% 83.8% 72.3% 83.8% 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.

Page 18: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 18 of 23

Summaries and Conclusions 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.

Page 19: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 19 of 23

Appendix The following files are included on the accompanying DVD: / 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)

Page 20: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 20 of 23

The pseudo-code design for processes.c is as follows: 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 }

Page 21: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 21 of 23

The pseudo-code design for threads.c is as follows: 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 }

Page 22: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 22 of 23

Bibliography [1] Xubuntu: Linux for human beings. Reference found on “xubuntu.org” Internet site at http://www.xubuntu.org/about/ on December 2, 2010. [2] Ubuntu Server Edition. Reference found on “ubuntu.com” Internet site at http://www.ubuntu.com/server/ on December 2, 2010. [3] VMware Workstation. Reference found on “vmware.com” Internet site at http://www.vmware.com/products/workstation/ on December 2, 2010. [4] Get to know Windows 7. Reference found on “microsoft.com” Internet site at http://www.microsoft.com/windows/windows-7/ on December 2, 2010. [5] Category: Prime Numbers. Reference found on “rosettacode.org” Internet site at http://rosettacode.org/wiki/Category:Prime_Numbers on January 30, 2011. [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.

Page 23: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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) ______________________________________________________________________________

______________________________________________________________________________Copyright © 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 23 of 23

Credits Xubuntu is a registered trademark of Canonical Ltd. Ubuntu is a registered trademark of Canonical Ltd. VMware is a registered trademark of VMware Inc. Windows is a registered trademark of Microsoft Corporation. Linux is a registered trademark of Linus Torvalds. Rosetta Code algorithm provided under GNU Free Documentation License 1.2. GNU Multi-Precision library provided under GNU Lesser General Public License. multi.c and pipe_nonblocking.c are Copyright (c) 2001 Aman Abdulla.

Page 24: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

COMP 8005, Assignment 1 January 2011

1

2

3

4

A B C D E F G H I

Test A

file I/O loops in each Process 

or Thread ...10 10 10 10 10

Process

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 1 of 5

5

6

7

8

9

Process with 10 file I/O 

loopsChild 1 Child 2 Child 3 Child 4 Child 5

Process 

averagesTotals

Process 

Totals vs 

Threads

run 1 start times 0.0008 0.0009 0.0010 0.0017 0.0006 0.0010 0.0050 87.7%

run 2 start times 0.0010 0.0018 0.0038 0.0053 0.0024 0.0029 0.0143 366.7%

run 3 start times 0.0010 0.0012 0.0010 0.0016 0.0017 0.0013 0.0065 151.2%

run 4 start times 0.0011 0.0013 0.0012 0.0017 0.0024 0.0015 0.0077 145.3%

10

11

12

13

14

15

16

run 5 start times 0.0035 0.0043 0.0015 0.0023 0.0021 0.0027 0.0137 342.5%

Process average start times 0.0015 0.0019 0.0017 0.0025 0.0018 0.0019 0.0094 203.4%

run 1 run times 0.0065 0.4175 3.1952 0.0028 0.0056 0.7255 3.6276 22.9%

run 2 run times 0.0031 0.4010 3.1160 0.0032 0.0062 0.7059 3.5295 36.3%

run 3 run times 0.0016 0.3959 3.1833 0.0032 0.0053 0.7179 3.5893 27.3%

run 4 run times 0.0018 0.3921 3.1176 0.0041 0.0081 0.7047 3.5237 51.7%

run 5 run times 0 0018 0 3895 3 1341 0 0077 0 0052 0 7077 3 5383 43 3%16

17

18

19

20

run 5 run times 0.0018 0.3895 3.1341 0.0077 0.0052 0.7077 3.5383 43.3%

Process average run times 0.0030 0.3992 3.1492 0.0042 0.0061 0.7123 3.5617 33.2%Process average total times 0.0044 0.4011 3.1509 0.0067 0.0079 0.7142 3.5711 33.3%

Thread with 10 file I/O 

loopsThread 1 Thread 2 Thread 3 Thread 4 Thread 5

Thread 

averagesTotals

Thread 

Totals vs 

Processes20

21

22

23

24

25

26

Processes

run 1 start times 0.0021 0.0011 0.0005 0.0009 0.0011 0.0011 0.0057 114.0%

run 2 start times 0.0010 0.0008 0.0006 0.0004 0.0011 0.0008 0.0039 27.3%

run 3 start times 0.0009 0.0009 0.0006 0.0004 0.0015 0.0009 0.0043 66.2%

run 4 start times 0.0010 0.0009 0.0007 0.0006 0.0021 0.0011 0.0053 68.8%

run 5 start times 0.0009 0.0007 0.0006 0.0013 0.0005 0.0008 0.0040 29.2%

Thread average start times 0.0012 0.0009 0.0006 0.0007 0.0013 0.0009 0.0046 49.2%

27

28

29

30

31

32

33

run 1 run times 3.0784 3.4788 3.0804 3.0858 3.0845 3.1616 15.8079 435.8%

run 2 run times 0.0030 3.4893 3.1106 0.0045 3.1092 1.9433 9.7166 275.3%

run 3 run times 0.0032 3.4758 3.0950 3.4775 3.0997 2.6302 13.1512 366.4%

run 4 run times 0.0040 3.5864 3.2055 0.0093 0.0080 1.3626 6.8132 193.4%

run 5 run times 0.3874 0.3855 3.5024 0.3860 3.5050 1.6333 8.1663 230.8%

Thread average run times 0.6952 2.8832 3.1988 1.3926 2.5613 2.1462 10.7310 301.3%Thread average total times 0 6964 2 8840 3 1994 1 3933 2 5625 2 1471 10 7357 300 6%33

34

Thread average total times 0.6964 2.8840 3.1994 1.3933 2.5625 2.1471 10.7357 300.6%

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 1 of 5

Page 25: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

COMP 8005, Assignment 1 January 2011

35

36

37

38

A B C D E F G H I

Test B

file I/O loops in each Process 

or Thread ...100,000 100,000 100,000 100,000 100,000

Process

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 2 of 5

39

40

41

42

43

Process with 100,000 file 

I/O loopsChild 1 Child 2 Child 3 Child 4 Child 5

Process 

averagesTotals

Process 

Totals vs 

Threads

run 1 start times 0.0017 0.0013 0.0131 0.0038 0.0101 0.0060 0.0300 810.8%

run 2 start times 0.0019 0.0029 0.0082 0.0072 0.0113 0.0063 0.0315 768.3%

run 3 start times 0.0009 0.0007 0.0029 0.0026 0.0027 0.0020 0.0098 196.0%

run 4 start times 0.0007 0.0006 0.0014 0.0018 0.0100 0.0029 0.0145 402.8%

44

45

46

47

48

49

50

run 5 start times 0.0008 0.0008 0.0006 0.0014 0.0112 0.0030 0.0148 321.7%

Process average start times 0.0012 0.0013 0.0052 0.0034 0.0091 0.0040 0.0201 479.0%

run 1 run times 0.0214 0.4396 3.3315 0.0153 0.0259 0.7667 3.8337 60.6%

run 2 run times 0.0218 0.4153 3.2627 0.0248 0.0201 0.7489 3.7447 27.5%

run 3 run times 0.0145 0.4213 3.2047 0.0170 0.0270 0.7369 3.6845 28.4%

run 4 run times 0.0102 0.4120 3.1892 0.0109 0.0123 0.7269 3.6346 40.1%

run 5 run times 0 0103 0 3982 3 2068 0 0102 0 0118 0 7275 3 6373 29 4%50

51

52

53

54

run 5 run times 0.0103 0.3982 3.2068 0.0102 0.0118 0.7275 3.6373 29.4%

Process average run times 0.0156 0.4173 3.2390 0.0156 0.0194 0.7414 3.7070 34.1%Process average total times 0.0168 0.4185 3.2442 0.0190 0.0285 0.7454 3.7271 34.2%

this vs Test A 379.3% 104.3% 103.0% 282.7% 359.6% 104.4%

Thread with 100,000 file I/O Thread 1 Thread 2 Thread 3 Thread 4 Thread 5

Thread Totals

Thread 

Totals vs

55

56

57

58

59

60

loopsThread 1 Thread 2 Thread 3 Thread 4 Thread 5

averagesTotals Totals vs 

Processes

run 1 start times 0.0011 0.0009 0.0007 0.0006 0.0004 0.0007 0.0037 12.3%

run 2 start times 0.0010 0.0008 0.0006 0.0006 0.0011 0.0008 0.0041 13.0%

run 3 start times 0.0008 0.0008 0.0007 0.0005 0.0022 0.0010 0.0050 51.0%

run 4 start times 0.0005 0.0008 0.0005 0.0010 0.0008 0.0007 0.0036 24.8%

run 5 start times 0.0011 0.0008 0.0007 0.0014 0.0006 0.0009 0.0046 31.1%

61

62

63

64

65

66

67

Thread average start times 0.0009 0.0008 0.0006 0.0008 0.0010 0.0008 0.0042 20.9%

run 1 run times 0.5144 0.7985 3.8853 0.5749 0.5576 1.2661 6.3307 165.1%

run 2 run times 0.7624 0.7624 4.0316 4.0262 4.0591 2.7283 13.6417 364.3%

run 3 run times 0.2476 0.7075 4.0049 4.0122 4.0230 2.5990 12.9952 352.7%

run 4 run times 0.5224 3.9509 3.5664 0.5247 0.5067 1.8142 9.0711 249.6%

run 5 run times 0.4274 4.0277 3.5258 4.0281 0.3810 2.4780 12.3900 340.6%

Thread average run times 0 4948 2 0494 3 8028 2 6332 1 9055 2 1771 10 8857 293 7%67

68

69

70

Thread average run times 0.4948 2.0494 3.8028 2.6332 1.9055 2.1771 10.8857 293.7%Thread average total times 0.4957 2.0502 3.8034 2.6340 1.9065 2.1780 10.8899 292.2%

this vs Test A 71.2% 71.1% 118.9% 189.0% 74.4% 101.4%

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 2 of 5

Page 26: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

COMP 8005, Assignment 1 January 2011

71

72

73

74

A B C D E F G H I

Test C

file I/O loops in each Process 

or Thread ...0 0 0 0 0

Process

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 3 of 5

75

76

77

78

79

Process with no file I/O Child 1 Child 2 Child 3 Child 4 Child 5Process 

averagesTotals

Process 

Totals vs 

Threads

run 1 start times 0.0012 0.0013 0.0010 0.0016 0.0023 0.0015 0.0074 238.7%

run 2 start times 0.0008 0.0008 0.0007 0.0019 0.0017 0.0012 0.0059 140.5%

run 3 start times 0.0008 0.0008 0.0007 0.0017 0.0020 0.0012 0.0060 176.5%

run 4 start times 0.0009 0.0008 0.0008 0.0021 0.0020 0.0013 0.0066 178.4%

80

81

82

83

84

85

86

run 5 start times 0.0006 0.0006 0.0006 0.0020 0.0018 0.0011 0.0056 60.2%

Process average start times 0.0009 0.0009 0.0008 0.0019 0.0020 0.0013 0.0063 132.9%

run 1 run times 0.0014 0.3897 3.0755 0.0030 0.0054 0.6950 3.4750 44.9%

run 2 run times 0.0015 0.3858 3.0408 0.0027 0.0075 0.6877 3.4383 42.5%

run 3 run times 0.0015 0.3829 3.0963 0.0034 0.0055 0.6979 3.4896 27.3%

run 4 run times 0.0016 0.3800 3.0473 0.0029 0.0077 0.6879 3.4395 30.5%

run 5 run times 0 0014 0 3857 3 1460 0 0030 0 0060 0 7084 3 5421 31 8%86

8788

89

90

run 5 run times 0.0014 0.3857 3.1460 0.0030 0.0060 0.7084 3.5421 31.8%

Process average run times 0.0015 0.3848 3.0812 0.0030 0.0064 0.6954 3.4769 34.1%Process average total times 0.0023 0.3857 3.0819 0.0049 0.0084 0.6966 3.4832 34.1%

this vs Test A 52.7% 96.2% 97.8% 72.3% 105.8% 97.5%

Thread with no file I/O Thread 1 Thread 2 Thread 3 Thread 4 Thread 5Thread 

Totals

Thread 

Totals vs

91

92

93

94

95

96

Thread with no file I/O Thread 1 Thread 2 Thread 3 Thread 4 Thread 5averages

Totals Totals vs 

Processes

run 1 start times 0.0009 0.0007 0.0005 0.0005 0.0005 0.0006 0.0031 41.9%

run 2 start times 0.0009 0.0007 0.0007 0.0013 0.0006 0.0008 0.0042 71.2%

run 3 start times 0.0009 0.0007 0.0006 0.0006 0.0006 0.0007 0.0034 56.7%

run 4 start times 0.0009 0.0008 0.0006 0.0004 0.0010 0.0007 0.0037 56.1%

run 5 start times 0.0026 0.0029 0.0027 0.0007 0.0004 0.0019 0.0093 166.1%96

97

98

99

100

101

102

0 00 6 0 00 9 0 00 0 000 0 000 0 00 9 0 0093 66 %

Thread average start times 0.0012 0.0012 0.0010 0.0007 0.0006 0.0009 0.0047 75.2%

run 1 run times 0.0029 0.3813 3.4891 0.3823 3.4889 1.5489 7.7445 222.9%

run 2 run times 0.0026 0.3962 3.6511 3.6518 0.3965 1.6196 8.0982 235.5%

run 3 run times 0.0023 3.4762 3.0923 3.0932 3.0964 2.5521 12.7604 365.7%

run 4 run times 0.3901 0.3898 3.4935 3.4949 3.4975 2.2532 11.2658 327.5%

run 5 run times 0.0016 0.3869 3.5822 3.5860 3.5845 2.2282 11.1412 314.5%

Th d i %103

104

105

106

Thread average run times 0.0799 1.0061 3.4616 2.8416 2.8128 2.0404 10.2020 293.4%Thread average total times 0.0811 1.0072 3.4627 2.8423 2.8134 2.0414 10.2068 293.0%

this vs Test A 11.5% 34.9% 108.2% 204.0% 109.8% 95.1%

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 3 of 5

Page 27: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

COMP 8005, Assignment 1 January 2011

107

108

109

A B C D E F G H I

Test D

On dedicated Internet 

server with 8 processors, 

and 100,000 file I/O loops 

per Process or Thread

100,000 100,000 100,000 100,000 100,000

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 4 of 5

109

110

111

112

113

per Process or Thread...

Process with 100,000 file 

I/O loopsChild 1 Child 2 Child 3 Child 4 Child 5

Process 

averagesTotals

Process 

Totals vs 

Threads

run 1 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%

run 2 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%

114

115

116

117

118

119

120

run 3 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 142.9%

run 4 start times 0.0002 0.0002 0.0002 0.0001 0.0002 0.0002 0.0009 128.6%

run 5 start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 166.7%

Process average start times 0.0002 0.0002 0.0002 0.0002 0.0002 0.0002 0.0010 153.1%

run 1 run times 0.1057 0.3595 2.4899 0.0153 0.0186 0.5978 2.9890 63.4%

run 2 run times 0.1210 0.3492 2.7298 0.0154 0.0193 0.6469 3.2347 34.7%

run 3 run times 0 1283 0 3213 2 4767 0 0158 0 0182 0 5921 2 9603 33 6%120

121

122

123

124

125

126

run 3 run times 0.1283 0.3213 2.4767 0.0158 0.0182 0.5921 2.9603 33.6%

run 4 run times 0.0965 0.3096 2.4551 0.0135 0.0225 0.5794 2.8972 42.7%

run 5 run times 0.1135 0.3241 3.0586 0.0187 0.0233 0.7076 3.5382 54.2%

Process average run times 0.1130 0.3327 2.6420 0.0157 0.0204 0.6248 3.1239 43.2%Process average total times 0.1132 0.3329 2.6422 0.0159 0.0206 0.6250 3.1249 43.2%

this vs Test B 672.2% 79.5% 81.4% 83.8% 72.3% 83.8%

126

127

128

129

130

Thread with 100,000 file I/O 

loopsThread 1 Thread 2 Thread 3 Thread 4 Thread 5

Thread 

averagesTotals

Thread 

Totals vs 

Processes

run 1 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%

run 2 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%

run 3 start times 0.0003 0.0001 0.0001 0.0001 0.0001 0.0001 0.0007 70.0%

131

132

133

134

135

136

137

run 4 start times 0.0002 0.0002 0.0001 0.0001 0.0001 0.0001 0.0007 77.8%

run 5 start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 60.0%

Thread average start times 0.0002 0.0001 0.0001 0.0001 0.0001 0.0001 0.0006 65.3%

run 1 run times 0.4505 0.4297 2.9049 0.4727 0.4546 0.9425 4.7124 157.7%

run 2 run times 0.0996 0.4342 2.9073 2.9318 2.9544 1.8655 9.3273 288.4%

run 3 run times 0.1680 2.9397 2.6254 2.9605 0.1171 1.7621 8.8107 297.6%

run 4 run times 0 1074 0 4190 2 9005 2 9119 0 4400 1 3558 6 7788 234 0%137

138

139

140

141

142

run 4 run times 0.1074 0.4190 2.9005 2.9119 0.4400 1.3558 6.7788 234.0%

run 5 run times 0.1154 0.4424 2.9040 0.1209 2.9401 1.3046 6.5228 184.4%

Thread average run times 0.1882 0.9330 2.8484 1.8796 1.3812 1.4461 7.2304 231.5%Thread average total times 0.1884 0.9331 2.8485 1.8797 1.3813 1.4462 7.2310 231.4%

this vs Test B 38.0% 45.5% 74.9% 71.4% 72.5% 66.4%

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 4 of 5

Page 28: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

COMP 8005, Assignment 1 January 2011

143

144

145

146

147

148

A B C D E F G H I

Summaries (Tests A, B, C)

average Process start time 0.0024 (sample size 75)

average Thread start time 0.0009 (sample size 75)

Thread vs Process 37.9%

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 5 of 5

148

149

150

151

152

153

Child / 

Thread 1

Child / 

Thread 2

Child / 

Thread 3

Child / 

Thread 4

Child / 

Thread 5

average Process run time 0.0067 0.4004 3.1565 0.0076 0.0106 (sample size 15 each)

average Thread run time 0.4233 1.9795 3.4877 2.2892 2.4265 (sample size 15 each)

Thread vs Process 6324.4% 494.4% 110.5% 30067.8% #######

154

155

156

157

158

159

160

average Process total time 0.0079 0.4018 3.1590 0.0102 0.0149 (sample size 15 each)

average Thread total time 0.4244 1.9805 3.4885 2.2899 2.4275 (sample size 15 each)

Thread vs Process 5390.6% 492.9% 110.4% 22464.7% #######

median Process run time 0.0018 0.3959 3.1460 0.0034 0.0075 (sample size 15 each)

median Thread run time 0.2476 0.7985 3.5024 3.0932 3.0997 (sample size 15 each)

Thread vs Process ####### 201 7% 111 3% 90976 5% #######160

161

162

163

164

165

Thread vs Process ####### 201.7% 111.3% 90976.5% #######

variance in Process run 

times 0.0001 0.0003 0.0064 0.0000 0.0001 (sample size 15 each)

variance in Thread run times 0.6038 2.6307 0.1045 2.8874 2.3663 (sample size 15 each)

Thread vs Process ####### ####### 1638.5% ######## #######

165

166

167

168

169

170

median Process start time 0.0009 0.0009 0.0010 0.0019 0.0023 (sample size 15 each)

median Thread start time 0.0009 0.0008 0.0006 0.0006 0.0008 (sample size 15 each)

Thread vs Process 100.0% 88.9% 60.0% 31.6% 34.8%

variance in Process start 

times 0.000001 ####### 0.000012 0.000003 ####### (sample size 15 each)

i i Th d t t

171

172

173

174

175

176

variance in Thread start 

times 0.000000 ####### 0.000000 0.000000 ####### (sample size 15 each)

Thread vs Process 52.6% 29.5% 2.4% 4.5% 2.1%

Notes:

Numbers above are in seconds, shown to 4 decimal places.

Original timings were to 6 decimal point precision: thus some rounding appears.176

177

178

Original timings were to 6 decimal point precision: thus some rounding appears.

Prime number 

decompositions calculated:

Child / 

Thread 1

Child / 

Thread 2

Child / 

Thread 3

Child / 

Thread 4

Child / 

Thread 5

998 = 2 * 499

992923727 = 

107 * 

9279661

2050700031 = 

3 * 3 * 3 * 

75951853

883993838 = 

2 * 7 * 13 * 

157 * 30937

100939437 = 

3 * 3 * 139 * 

80687

Copyright (c) 2011. Arthur (Wesley) Kenzie. All Rights Reserved. Page 5 of 5

Page 29: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

1 /*********************************************************************2  * Author and Copyright (c) A. Abdulla, January 20013  * Original program name: pipe_nonblocking.c4  * Modified program name: processes.c5  * Modified by: Arthur (Wesley) Kenzie (BCIT Student ID A00242330)6  * Modified date: January 28, 20117  * Latest version: 1.07a8  * Description: this program is adapted to demonstrate 3‐9 processes9  * to be compared to 3‐9 threads in the separate threads.c program10  * for Assignment 1 in COMP 800511  * thanks to rosettacode.org/Prime_decomposition#C12  * uses the GMP (GNU Multiple Precision Library for the computations13 **********************************************************************/14 /********************************************************************15  * compile as follows:16  * gcc ‐Wall ‐o a1p processes.c primedecompose.c ‐lgmp ‐lm17  * to link in gmp and math libraries18 *********************************************************************/19 /********************************************************************20  * run as follows:21  * ./a1p [‐‐debug] [‐‐skipfileio] [‐‐skipcpu] [‐‐ioloops=x] 1 2 3 4 5 6 7 8 922  * where 1‐9 are 3‐9 integer numbers23  * and ‐‐ioloops=x will only be used if ‐‐skipfileio is not included24  * and x value in ‐‐ioloops= parameter is 10^x loops25 *********************************************************************/2627 #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>3637 #define MSGSIZE         1638 #define MAX_FACTORS 102439 #define BASE10          1040 #define MINNUMS         341 #define MAXNUMS         942 #define BCOMM           0 // communicate through pipes or not4344 /*‐‐‐‐‐‐ 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 *);4950 /*‐‐‐‐‐‐‐ 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!6061 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 line68     uint n, processcount, childnum;69     int pfd[argc][2];70     char * debug_parm = "‐‐debug";

Page 30: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

71     char * skipfileio_parm = "‐‐skipfileio";72     char * skipcpu_parm = "‐‐skipcpu";73     char * ioloops_parm = "‐‐ioloops=";74     uint ioloops_len = strlen(ioloops_parm);7576     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 mode90         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 threads96         if ( strcmp((char *)argv[n], skipfileio_parm) == 0 )97         {98             bfileio = 0;99             continue;100         }101         // ‐‐skipcpu parameter (anywhere) will skip cpu work in threads102         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 threads108         // where ‐‐ioloops=3 will do 1,000 loops109         // ‐‐ioloops=5 will do 100,000 loops110         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         }

Page 31: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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 }178179 /*‐‐‐‐‐‐‐ Parent process function ‐‐‐‐‐‐‐*/180 // parameter int p[2] is array of pipes to and from child process181 // p[0] is read descriptor of pipe from child182 // p[1] is write descriptor of pipe to child183 // parameter const uint bcomm is boolean whether to read messages being sent from child process to parent184 // returns int 0 if finished successfully185 // returns int <> 0 if finished unsuccessfully186 int parent (int p[2], const uint bcomm)187 {188     int nread;189     char buf[MSGSIZE];190191     // if not bcomm then nothing happens in this function192     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");

Page 32: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

211                         return(0);212                     }213                     else214                     {215                         printf ("MSG = %s\n", buf);216                     }217             }218         }219     }220     return(0);221 }222223 /*‐‐‐‐‐‐ Child process function ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/224 // parameter int p[2] is array of pipes to and from parent process225 // p[0] is read descriptor of pipe from parent226 // p[1] is write descriptor of pipe to parent227 // parameter const uint bcomm is boolean to indicate whether child should communicate with parent over pipes228 // parameter uint childnum is (arbitrary) number of this child process229 // parameter num is long long unsigned integer to be decomposed by this child process230 // parameter dtime is double holding time at start of fork which created this child process231 // returns void232 // child process kills itself with exit(0) when done233 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;242243     close (p[0]);    /* close the read descriptor */244245     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 in257     if ( bcpu )258     {259         printf("child %i: ", childnum);260         icalc = calc(s);261         printf("\n");262     }263264     // now do some file i/o stuff265     if ( bfileio )266     {267         sprintf(filename, "child%i.txt", childnum);268         fp = fopen(filename, "w");269         if ( fp == NULL )270         {271             // error272             printf("error: child %i file error\n", childnum);273         }274         else275         {276             if ( bdebug )277             {278                 printf("debug: child %i file %s initialized\n", childnum, filename);279             }

Page 33: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

280             for ( icalc=0; icalc<ioloops; icalc++ )281             {282                 fputs(wbuffer, fp);283                 fgets(rbuffer, 2, fp);284             }285             fclose(fp);286         }287     }288289     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 }299300 /* calc function */301 // thanks to rosettacode.org/Prime_decomposition#C302 // January 2011303 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);309310     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 }317318 /*‐‐‐‐‐‐‐‐‐‐ Error function ‐‐‐‐‐‐*/319 // returns void320 // parameter char * is message to be printed before program aborts321 void fatal (char *s)322 {323   perror (s);    /* print error msg and die */324   exit(1);325 }

Page 34: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

1 /*******************************************************************2  * Author and Copyright (c) A. Abdulla, January 20013  * Original program name: multi.c4  * Modified program name: threads.c5  * Modified by: Arthur (Wesley) Kenzie (BCIT Student ID A00242330)6  * Modified date: January 28, 20117  * Latest version: 1.02f8  * Description: this program is adapted to demonstrate 3‐9 threads9  * to be compared to 3‐9 processes in the separate processes.c program10  * for Assignment 1 in COMP 800511  * thanks to rosettacode.org/Prime_decomposition#C12  * uses the GMP (GNU Multiple Precision Library for the computations13 *********************************************************************/14 /********************************************************************15  * compile as follows:16  * gcc ‐Wall ‐o a1t threads.c primedecompose.c ‐lgmp ‐lpthread ‐lm17  * to link in gmp, pthread and math libraries18 *********************************************************************/19 /********************************************************************20  * run as follows:21  * ./a1t [‐‐debug] [‐‐skipfileio] [‐‐skipcpu] [‐‐ioloops=x] 1 2 3 4 5 6 7 8 922  * where 1‐9 are 3‐9 integer numbers23  * and ‐‐ioloops=x will only be used if ‐‐skipfileio is not included24  * and x value in ‐‐ioloops= parameter is 10^x loops25 *********************************************************************/2627 #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>3738 #define _REENTRANT39 #define DCE_COMPAT40 #define MAX_FACTORS 102441 #define BASE10          1042 #define MINNUMS         3 // min number of threads43 #define MAXNUMS         9 // max number of threads4445 /*‐‐‐‐‐‐ Function prototypes ‐‐‐‐‐‐‐‐‐‐*/46 void * calcplusio (void *);47 void fatal (char *);4849 /*‐‐‐‐‐‐‐‐‐‐‐‐ Mutex Variables ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/50 pthread_mutex_t decomposeLock = PTHREAD_MUTEX_INITIALIZER;5152 /*‐‐‐‐‐‐‐ 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 number59         long int linum; // long int to be decomposed60         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 thread65     };66 struct thread_data thread_data_array[MAXNUMS]; // passed to each thread6768 int main(int argc, char **argv)69 {70     struct timeval ttp;

Page 35: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

71     double tt1, tt2, tt3;72     gettimeofday(&ttp, NULL);73     tt1 = ttp.tv_sec+(ttp.tv_usec/1000000.0); // program start time74     char errstr[255];75     long unsigned int linum[argc]; // array of integers entered on command line76     uint n, threadcount;77     pthread_t thread[argc];78     uint threadnum;79     int pint; // pthread_create() result80     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);8586     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 mode96         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 threads102         if ( strcmp((char *)argv[n], skipfileio_parm) == 0 )103         {104             bfileio = 0;105             continue;106         }107         // ‐‐skipcpu parameter (anywhere) will skip cpu work in threads108         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 threads114         // where ‐‐ioloops=3 will do 1,000 loops115         // ‐‐ioloops=5 will do 100,000 loops116         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++ )

Page 36: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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 exiting170 }171172 /* calcplusio function */173 // thanks to rosettacode.org/Prime_decomposition#C174 // based on calc() function175 // returns void (since this is a thread(ed) function)176 // parameter td is thread_array struct with thread data177 // January 2011178 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 );187188     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     }201202     // do some cpu computation stuff on the integer passed in203     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);

Page 37: BCIT COMP 8005 multi-threaded vs multi-process program analysis assignment by Wesley Kenzie, February 2011

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     }217218     // now do some file i/o stuff219     if ( parm‐>bfileio )220     {221         sprintf(filename, "thread%i.txt", parm‐>threadnum);222         sprintf(wbuffer, "%li", parm‐>linum); // write buffer223         fp = fopen(filename, "w");224         if ( fp == NULL )225         {226             // error227             printf("error: thread %i file %s could not be created\n", parm‐>threadnum, filename);228         }229         else230         {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);250251     pthread_exit((void *) NULL);252 }253254 /*‐‐‐‐‐‐‐‐‐‐ Error function ‐‐‐‐‐‐*/255 // returns void256 // parameter char * is message to be printed before program aborts257 void fatal (char *s)258 {259   perror (s);    /* print error msg and die */260   exit(1);261 }