Threads
Lab exercises for February 20th.
The goals for this assignment are:
-
Understanding the pthread library
-
Working with ucontext
We will use the same repository as last week: Labs Repo. Click on the link and then accept and merge the pull request.
1. Matrix Add Due Feb 20
In the files, matrix.c
, implement a program that uses M threads to add
two matrices, each stored in its own binary file, and saving the result into a third file.
$ ./matrix
usage: ./matrix
$ ./matrix 1 A1 B2
Dimensions do not match!
$ ./matrix 1 A1 B1
Starting thread 139848748009024 (idx = 0)
duration: 0.00
$ ./readmat A1
0 -8 -6 8
0 4 -7 9
1 7 0 5
$ ./readmat B1
1 -6 -2 3
-6 -1 -9 8
-7 8 -5 -5
$ ./readmat A1+B1
1 -14 -8 11
-6 3 -16 17
-6 15 -5 0
$ ./matrix 1 A4 B4
Starting thread 139696590177856 (idx = 0)
duration: 0.36
$ ./matrix 4 A4 B4
Starting thread 140698237380160 (idx = 0)
Starting thread 140698228987456 (idx = 1)
Starting thread 140698220594752 (idx = 2)
Starting thread 140698212202048 (idx = 3)
duration: 0.21
$ ./matrix 8 A4 B4
Starting thread 140559920776768 (idx = 1)
Starting thread 140559912384064 (idx = 2)
Starting thread 140559903991360 (idx = 3)
Starting thread 140559929169472 (idx = 0)
Starting thread 140559895598656 (idx = 4)
Starting thread 140559887205952 (idx = 5)
Starting thread 140559878813248 (idx = 6)
Starting thread 140559870420544 (idx = 7)
duration: 0.23
Requirements/Hints:
-
Time how long it takes to compute the result when you have 8, 4, or a single thread.
-
Leverage spatial locality to ensure the best performance, e.g. split the work by rows in each matrix.
-
Use the program
readmat.c
to test that your program runs correctly -
Name the output file based on the two inputs, e.g. <Mat1>+<Mat2>
-
Use gettimeofday(), defined in
sys/time.h
to get the duration of your program.
struct timeval ts, te;
gettimeofday(&ts, NULL);
...
gettimeofday(&te, NULL);
double time = te.tv_sec - ts.tv_sec + (te.tv_usec - ts.tv_usec)/1.e6;
printf("duration: %.4f\n", time);
The matrices you need to add are stored in a binary file that stores a sequence of integers.
-
The first integer is the number of rows
-
The second integer is the number of columns
-
The remaining integers are the values of the matrix, stored in row-major order.
To test with large matrices, download them from the website (but don’t check them in!)
$ wget https://alinen.net/A4
$ wget https://alinen.net/B4
2. Funny functions Due Feb 23
Implement the following programs based on ucontext.
2.1. Return
In the file, hello_context.c
, modify the program so it returns to main after executing f().
Use the code from lecture to help you!
$ ./hello_context
Hello World
End of main
2.2. Alternate
In the file, alternate.c
, write a program that alternates between two
functions indefinitely.
$ ./alternate
odd:1
even:0
odd:3
even:2
odd:5
^C
Send a signal to the alternate
process. In your C file, answer the following questions:
-
What happens when a signal is delivered?
-
How do signals affect the execution of a context?
Hints:
-
Alternate between main and another function.
-
Make your two ucontext variables global so that main can swap to the function, and then the function can swap back to main
-
The example above uses
nanosleep
to pause inside the loop -
The example above sets printf to flush immediately (e.g. show output text immediately) to make the output cleaner. This is done with the command
setvbuf(stdout, 0, _IOLBF, 0);
.
Above, main loops over odd numbers and the function loops over even numbers (see below). Each iteration, they swapcontext
.
void nextEven()
{
struct timespec delay = { 1, 0 };
for (unsigned int i = 0;; i += 2) {
printf("even:%d\n", i);
nanosleep(&delay, 0);
}
}
2.3. Alarm
Can you write a program that alternates between two functions at a set interval?
In the file, alarm.c
, write a program that alternates between two functions at a set interval.
Use a kernel timer like in the sig_alarm demo from class.
$ **./alarm**
even:0
even:2
odd:1
odd:3
even:4
even:6
odd:5
odd:7
Hints:
-
Above, we defined two functions in addition to main,
nextEven()
andnextOdd()
. -
The signal handler switches between
nextEven
andnextOdd
using a global variable that specifies which should run -
After setting up the contexts and signals, main calls
pause
in an infinite loop. -
The timer triggers every 2 seconds and each functions sleep 1 second between printing. Thus, we see two prints before switching to the next function.