多处理器编程从入门到放弃

本讲内容:多处理器编程:从入门到放弃:

  • 入门:多线程编程库
  • 放弃:原子性、可见性、顺序

入门

每个线程都有自己的堆栈,如何确定各自的堆栈大小?

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
#include "thread.h"

void * volatile low[64];
void * volatile high[64];

void update_range(int T, void *ptr) {
if (ptr < low[T]) low[T] = ptr;
if (ptr > high[T]) high[T] = ptr;
}

void probe(int T, int n) {
update_range(T, &n);
long sz = (uintptr_t)high[T] - (uintptr_t)low[T];
if (sz % 1024 < 32) {
printf("Stack(T%d) >= %ld KB\n", T, sz / 1024);
}
probe(T, n + 1); // Infinite recursion
}

void Tprobe(int T) {
low[T] = (void *)-1;
high[T] = (void *)0;
update_range(T, &T);
probe(T, 0);
}

int main() {
setbuf(stdout, NULL);
for (int i = 0; i < 4; i++) {
create(Tprobe);
}
}

为什么要 setbuf(stdout, NULL) 关闭缓冲区?

有时候一个printf明明在crash前的代码运行了,但没有得到输出,原因是什么呢?
是因为printf先把输出放在缓冲区里。

这段代码的核心思想就是无穷递归,利用函数参数存储在栈空间里估算栈的大小。

放弃:原子性

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "thread.h"

#define N 100000000

long sum = 0;

void Tsum() {
for (int i = 0; i < N; i++) {
sum++;
}
}

int main() {
create(Tsum);
create(Tsum);
join();
printf("sum = %ld\n", sum);
}

编译优化 -O2得到答案 200000000

编译器直接计算出答案,一条指令赋值给sum

编译优化 -O1得到答案 100000000


多处理器编程从入门到放弃
http://example.com/2023/08/02/操作系统/jyy操作系统/多处理器编程从入门到放弃/
作者
LiuZhaocheng
发布于
2023年8月2日
许可协议