• 第26章 并发:介绍


    Homework(Simulation):

    This program, x86.py, allows you to see how different thread interleavings either cause or avoid race conditions. See the README for details on how the program works, then answer the questions below.

    questions:

    1. Let’s examine a simple program, “loop.s”. First, just read and understand it. Then, run it with these arguments (./x86.py -p loop.s -t 1 -i 100 -R dx) This specifies a single thread, an interrupt every 100 instructions, and tracing of register %dx. What will %dx be during the run? Use the -c flag to check your answers; the answers, on the left, show the value of the register (or memory value) after the instruction on the right has run.

    loop.s

    1. .main # 程序开始
    2. .top # 循环开始处
    3. sub $1,%dx # 将寄存器%dx中的值减1
    4. test $0,%dx # 测试该值是否大于等于0
    5. jgte .top # 如果该值大于等于0则跳转到.top
    6. halt # 程序结束

    只有一个线程,中断不会有什么影响 

    python3 x86.py -p loop.s -t 1 -a dx=105 -i 100 -R dx -c

    2. Same code, different flags: (./x86.py -p loop.s -t 2 -i 100 -a dx=3,dx=3 -R dx) This specifies two threads, and initializes each %dx to 3. What values will %dx see? Run with -c to check. Does the presence of multiple threads affect your calculations? Is there a race in this code?

    不存在竞争,因为每个线程都有各自的寄存器相互独立

    python3 x86.py -p loop.s -t 2 -a dx=3,dx=3 -i 100 -R dx -c

    3. Run this: ./x86.py -p loop.s -t 2 -i 3 -r -a dx=3,dx=3 -R dx This makes the interrupt interval small/random; use different seeds (-s) to see different interleavings. Does the interrupt frequency change anything?

    每次中断,会发生线程上下文切换,但因为每个线程各自的寄存器相互独立,结果不变

    python3 x86.py -p loop.s -t 2 -i 3 -r -a dx=3,dx=3 -R dx -s 0 -c

    python3 x86.py -p loop.s -t 2 -i 3 -r -a dx=3,dx=3 -R dx -s 1 -c 

    python3 x86.py -p loop.s -t 2 -i 3 -r -a dx=3,dx=3 -R dx -s 2 -c 

    4. Now, a different program, looping-race-nolock.s, which accesses a shared variable located at address 2000; we’ll call this variable value. Run it with a single thread to confirm your understanding: ./x86.py -p looping-race-nolock.s -t 1 -M 2000 What is value (i.e., at memory address 2000) throughout the run? Use -c to check.

    x从0变为1

    python3 x86.py -p looping-race-nolock.s -t 1 -M 2000 -R ax,bx -c

    5. Run with multiple iterations/threads: ./x86.py -p looping-race-nolock.s -t 2 -a bx=3 -M 2000 Why does each thread loop three times? What is final value of value?

    循环的条件是bx中的值大于0,因此要循环3次

    而每个线程拥有各自的寄存器且相互独立,所以每个线程都会循环3次

    x的最终值为6

    python3 x86.py -p looping-race-nolock.s -t 2 -a bx=3 -M 2000 -R ax,bx -c

    6. Run with random interrupt intervals: ./x86.py -p looping-race-nolock.s -t 2 -M 2000 -i 4 -r -s 0 with different seeds (-s 1, -s 2, etc.) Can you tell by looking at the thread interleaving what the final value of value will be? Does the timing of the interrupt matter? Where can it safely occur? Where not? In other words, where is the critical section exactly?

    临界区

    1. mov 2000, %ax # get 'value' at address 2000
    2. add $1, %ax # increment it
    3. mov %ax, 2000 # store it back

    如果中断发生在临界区之外则是安全的,否则有可能会出现同步错误 

    x=5

    python3 x86.py -p looping-race-nolock.s -t 2 -i 4 -r -a bx=3 -M 2000 -R ax,bx -s 0 -c

    x=3

    python3 x86.py -p looping-race-nolock.s -t 2 -i 4 -r -a bx=3 -M 2000 -R ax,bx -s 1 -c

    x=6

    python3 x86.py -p looping-race-nolock.s -t 2 -i 4 -r -a bx=3 -M 2000 -R ax,bx -s 2-c

    7. Now examine fixed interrupt intervals: ./x86.py -p looping-race-nolock.s -a bx=1 -t 2 -M 2000 -i 1 What will the final value of the shared variable value be? What about when you change -i 2, -i 3, etc.? For which interrupt intervals does the program give the “correct” answer?

    x=1 

    python3 x86.py -p looping-race-nolock.s -t 2 -a bx=1 -M 2000 -R ax,bx -i 1 -c

    x=1

    python3 x86.py -p looping-race-nolock.s -t 2 -a bx=1 -M 2000 -R ax,bx -i 2 -c

    x=2 正确

    python3 x86.py -p looping-race-nolock.s -t 2 -a bx=1 -M 2000 -R ax,bx -i 3 -c

    8. Run the same for more loops (e.g., set -a bx=100). What interrupt intervals (-i) lead to a correct outcome? Which intervals are surprising?

    因为临界区由3条指令组成而循环部分由6条指令组成,所以中断频率如果为3的倍数就是安全的,

    这样就可以确保中断不会发生在临界区

    python3 x86.py -p looping-race-nolock.s -t 2 -a bx=100 -M 2000 -R ax,bx -i 3 -c

    9. One last program: wait-for-me.s. Run: ./x86.py -p wait-for-me.s -a ax=1,ax=0 -R ax -M 2000 This sets the %ax register to 1 for thread 0, and 0 for thread 1, and watches %ax and memory location 2000. How should the code behave? How is the value at location 2000 being used by the threads? What will its final value be?

    Thread0将地址2000处的值设为1,Thread1检查该值是否为1,因此地址2000处的值最终为1

    python3 x86.py -p wait-for-me.s -a ax=1,ax=0 -R ax,cx -M 2000 -c

    10. Now switch the inputs: ./x86.py -p wait-for-me.s -a ax=0,ax=1 -R ax -M 2000 How do the threads behave? What is thread 0 doing? How would changing the interrupt interval (e.g., -i 1000, or perhaps to use random intervals) change the trace outcome? Is the program efficiently using the CPU?

    Thread0会不断重复执行1000-1004这5条指令,直到第一次中断,线程上下文切换至Thread1,Thread1会修改地址2000处的值,此后Thread0将结束循环

    因此中断间隔越长,CPU效率越低

    python3 x86.py -p wait-for-me.s -a ax=0,ax=1 -R ax,cx -M 2000 -c

    python3 x86.py -p wait-for-me.s -a ax=0,ax=1 -R ax,cx -M 2000 -i 1000 -c

  • 相关阅读:
    C语言:求n的阶乘
    EasyExcel实现对excel文件读写
    MYSQL-存储引擎
    性能分析插件
    大数据必学Java基础(十四):Java中的运算符
    JS中Cookie的基本使用
    Html- 阻止子元素事件触发父元素事件(事件冒泡)
    告别EXCEL,易点易动库存管理系统帮助企业提升固定资产管理效率
    我开源了团队内部基于SpringBoot Web快速开发的API脚手架stater
    3D视觉学习路线 + 路线规划
  • 原文地址:https://blog.csdn.net/suitaox26456/article/details/127701122