wys的个人博客

你有很多事放不下?做人要潇洒一点~

0%

cs61c_lab10

cs61c_lab10

Part1: Multi-threading programming using OpenMP

Exercise 2 - Vector Addition

方法1如下:

1
2
3
4
5
6
7
8
9
void v_add_optimized_adjacent(double* x, double* y, double* z) {
#pragma omp parallel
{
int num_threads = omp_get_num_threads();
int id = omp_get_thread_num();
for(int i=id; i<ARRAY_SIZE; i+= num_threads)
z[i] = x[i] + y[i];
}
}

方法二如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void v_add_optimized_chunks(double* x, double* y, double* z) {
#pragma omp parallel
{
int num_threads = omp_get_num_threads();
int id = omp_get_thread_num();
if (id != num_threads - 1) {
for(int i=ARRAY_SIZE/num_threads*id; i<ARRAY_SIZE/num_threads*(id + 1); i++)
z[i] = x[i] + y[i];
}
else {
for(int i=ARRAY_SIZE/num_threads*id; i<ARRAY_SIZE; i++)
z[i] = x[i] + y[i];
}
}
}

Exercise 3 - Dot Product

不使用reduction的代码如下,不知道题目想干什么,这部分参考了1 ,感觉还是不是很符合题意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
double dotp_manual_optimized(double* x, double* y, int arr_size) {
double global_sum = 0.0;
int num_threads;
#pragma omp parallel
{
num_threads = omp_get_num_threads();
}
double *sum = (double *)malloc(num_threads * sizeof(double));
memset(sum, 0, sizeof(sum));
#pragma omp parallel
{
int id = omp_get_thread_num();
double now = 0.0;
for (int i = id; i < arr_size; i += num_threads) {
now += x[i] * y[i];
}
sum[id] = now;
}
for (int i = 0; i < num_threads; i ++) {
global_sum += sum[i];
}
free(sum);
return global_sum;
}

下面是使用了reduction的代码:

1
2
3
4
5
6
7
8
9
10
double dotp_reduction_optimized(double* x, double* y, int arr_size) {
double global_sum = 0.0;
#pragma omp parallel
{
#pragma omp for reduction(+:global_sum)
for (int i = 0; i < arr_size; i++)
global_sum += x[i] * y[i];
}
return global_sum;
}

Part 2: Intro to multi-processing programming

这题貌似直接使用gcc-11会报错,可以改用gcc-9。或者把变量的定义放进server_utils.c 然后将 server_utils.h 中的变量加上extern

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
while (1) {
client_socket_number = accept(*socket_number,
(struct sockaddr *) &client_address,
(socklen_t * ) & client_address_length);
if (client_socket_number < 0) {
perror("Error accepting socket");
continue;
}

printf("Accepted connection from %s on port %d\n",
inet_ntoa(client_address.sin_addr), client_address.sin_port);

pid_t parent_pid = getpid();
#ifdef PROC
// PART2 TASK: Implement forking
/* YOUR CODE HERE */
pid_t child_pid = fork();
if (child_pid != 0) {
// Kill child process if parent dies
int r = prctl(PR_SET_PDEATHSIG, SIGTERM);

/* YOUR CODE HERE */
dispatch(client_socket_number);
// Exit with code 1 when there was an error,
// or when the parent has been killed
if (r == -1 || getppid() != parent_pid) {
perror(0);
exit(1);
}

/* YOUR CODE HERE */
exit(EXIT_SUCCESS);
}
#else
dispatch(client_socket_number);
#endif
}