Click here to load reader
Date post: | 27-Jul-2015 |
Category: |
Documents |
Upload: | wesley-kenzie |
View: | 323 times |
Download: | 1 times |
Click here to load reader
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
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.
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.
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:
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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
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.
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.
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.
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)
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 }
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 }
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.
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.
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
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
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
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
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
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";
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 }
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");
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 }
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 }
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;
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++ )
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);
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 }