Skip to content

Instantly share code, notes, and snippets.

@Cee
Last active August 29, 2015 14:24
Show Gist options
  • Save Cee/e66cd46abcf6ac203f94 to your computer and use it in GitHub Desktop.
Save Cee/e66cd46abcf6ac203f94 to your computer and use it in GitHub Desktop.
Multicore

1 - 并行计算概述

  1. 并行计算的意义
    • 解决计算挑战的必经之路
    • 现在并行计算很成熟
      • 分布式集群
      • 多核
      • 开发环境
  2. 并行计算的三个方面
    • 并行计算机体系结构
    • 并行编程
    • 并行算法
  3. 并发和并行
    • 并发(Concurrency):两个或多个线程在同时进行
    • 并行(Parallelism):两个或多个线程在同事执行
  4. 加速比
    • 加速比 = 串行算法执行时间 / 并行算法执行时间
    • 描述对程序并行化之后获得的性能收益
    • Amdahl 定律 - 固定问题规模
      • 加速比 = 1 / (S + (1 - S) / n)
      • S:程序中串行部分的比例
      • n:机器规模或处理器核的数目
    • Gustafson 定律 - 固定时间
      • 扩展加速比 = ( 1 - S ) * n + S

2 - 并行计算模型与系统

  1. Flynn 分类法
    • 根据指令和数据流如何执行分类
    • 分为四种
      • SISD (Single Instruction, Single Data stream)
        • 普通 PC 和工作站
        • 受限于内部信息传输速度
      • SIMD (Single Instruction, Multiple Data Streams)
        • CRAY
        • Intel MMX
      • MISD (Multiple Instructions, Single Data Stream)
        • 理论模型
        • 或者用于容错性
        • 流水线
      • MIMD (Multiple Instructions, Multiple Data Streams)
        • 理想的并行机模型
        • 异步
        • 分类
          • Shared Memory
            • 限制:可靠性和可扩展性,内存组件故障将导致整个系统故障
          • Distributed Memory
            • 可擴展性
            • IPC 通訊
          • SPMD(Single Program, Multiple Data)
            • 同一程序对于不同数据给不同处理器执行
          • MPMD
  2. 共享存储器结构
    • 无共享体系
    • 共享磁盘体系
    • 共享存储体
  3. 并行计算机模型
    • 定义:通过语义属性和性能属性描述
    • 操作和开销
      • 三种操作
        • 计算操作
        • 并行操作:管理线程 / 进程,例如创建终结 / 上下文切换
        • 进程间同步操作
      • 四种开销
        • 并行开销:进程管理引起
        • 通信开销:处理器交换信息
        • 同步开销:执行同步操作
        • 负载不平衡开销:部分处理器空闲然而部分繁忙
    • 不可并行:Affman 函数 / 工作流
    • PRAM 模型
      • Parallel Random Access Machine
      • n 个处理器,1 个共享空间,1 个公共时钟
      • 唯一的开销是负载不平衡开销
      • 应用
        • 串行:2N - 1,N 次乘,N - 1 次加
        • 并行:[2N - 1 - (n - 1)] / n + logn
        • N>>n,加速比为 n
      • 优点:简单
      • 缺点:零通信开销不可能
    • APRAM 模型(不考)
      • 同步路障
      • 各自的时钟,但是可以加入同步指令
    • BSP 模型
      • 由 n 个处理器-存储器对组成
      • 分布式 MIMD
  4. 内存访问模型
    • 多级存储体系结构
      • CPU
      • 寄存器
      • Cache:直接映射 / n 路组关联映射 / 全关联映射
      • 局部存储
      • 远程存储
    • 并行计算机访问模型
      • UMA(Uniform Memory Access)
        • 物理存储器被所有节点共享
        • 所有节点访问任意存储单元的时间相同
        • 发生访存竞争时,仲裁策略平等对待每个节点,即每个节点机会均等
        • 各节点的 CPU 可带有局部私有高速缓存
        • 外围 I/O 设备也可以共享,且每个节点有平等的访问权利
      • NUMA(Non-Uniform Memory Access)
        • 物理存储器被所有节点共享,任意节点可以直接访问任意内存模块
        • 节点访问内存模块的速度不同,访问本地存储模块的速度一般是访问其他节点内存模块的 3 倍以上
        • 发生访存竞争时,仲裁策略对节点可能是不等价的
        • 各节点的 CPU 可带有局部私有高速缓存
        • 外围 I/O 设备也可以共享,但对各节点是不等价的
      • COMA(不考)
      • NORMA(不考)
      • CC-NUMA(不考)
    • 串行一致性:写直达,回写
    • 监听一致性:写无效,写更新
  5. 典型并行计算系统
    • SMP(对称存储多处理器)
      • UMA
      • 结构对称
      • 存储器和 I/O 负载大
      • 扩展性差
    • PVP(并行向量处理机)
    • MPP(大规模并行处理)
    • Cluster(集群)
      • 各个节点都是完整的计算机
      • 各个节点都有操作系统

3 - 并行编程基础

综述

  1. 并行编程:算法构造并行程序的活动
  2. 三种并行编程模型
    • 共享存储器编程
    • 消息传递编程
    • 数据并行编程

并行编程模型

  1. 显式并行和隐式并行

    • 代码中使用语言构造的显式说明
    • 编译器的优化
  2. 三种显式编程模型特点

    特点 数据并行 消息传递 共享存储
    控制流
    同步 松散同步 异步 异步
    地址空间
    交互 隐式 显式 显式
    数据分配 隐式或半显式 显式 隐式或半显式
    可移植性 SMP/DSM/MPP 基本主流并行计算机 SMP/DSM
    存储 半隐式 显式 隐式

    OpenMP 是共享存储

并行编程的策略和方法

  1. 分解方式
    • 任务分解
    • 数据分解
    • 数据流分解
  2. 任务分解
    • 打开文档后可以立刻输入
    • 后台在加载
  3. 设计模式
    • 任务并行:任务分解/数据分解
    • 分治:任务分解/数据分解
    • 几何分解:数据分解
    • 流水线:数据流分解

4 - Windows 多核编程

  1. 进程和线程

    • 所谓线程就是操作系统中能够进行运算调度的最小单位
    • 所谓进程就是一个或多个线程组成,并且需要系统资源的一个地址空间
  2. 线程 API 的实现层次

    • 操作系统层(如Win32 API)
    • 库或运行时环境(MFC, .net框架)
    • 专门的多线程库(pthread)
  3. 创建线程

    // Basic
    CreateThread();
    ExitThread();
    // Widely Used
    _beginthreadex();
    _endthreadex();
    // For MFC
    AfxBeginThread();
    AfxEndThread();
    // paras
    _beginthreadex(security, stack_size, start_address, arglist, initflag, threadID);
    _endthreadex(return_val);
  4. 线程/进程号

    GetCurrentProcess();
    GetCurrentThread();
    GetCurrentProcessId();
    GetCurrentThreadId();
  5. 管理线程

    SuspendThread();
    ResumeThread();
    TerminateThread();
    // paras
    (thread, exit_code)
  6. 互锁函数

    InterlockedIncrement();
    InterlockedDecrement();
    InterlockedExchange();
    InterlockedExchangePointer();
    InterlockedExchangeAdd();
    InterlockedCompareExchange();
    // paras
    InterlockedExchange(&pointer, TRUE); // return pointer old value and pointer = TRUE
  7. 临界区

    void InitializeCriticalSection();
    void EnterCriticalSection();
    void LeaveCriticalSection();
    void DeleteCriticalSection();
    // paras
    LPCRITICAL_SECTION // type CRITICAL_SECTION address

    注意 __finally 执行 Leave

  8. 内核对象同步

    WaitForSingleObject();
    // paras
    (thread, milliseconds)
    // return value
    WAIT_OBJECT_0
    WAIT_TIMEOUT
    WAIT_FAILED
    WaitForMutlipleObjects();
    // paras
    (count, objects, fWaitAll, milliseconds)
    // fWaitAll
    // TRUE: 所有对象
    // FALSE: 一个对象
    // return value
    WAIT_OBJECT_0
    WAIT_OBJECT_0 + 1
    ...
    WAIT_OBJECT_0 + dwCount - 1
    WAIT_TIMEOUT
    WAIT_FAILED
  9. 事件

    CreateEvent(security, reset, init_state, name);
    SetEvent(hEvent);
    ResetEvent(hEvent);
  10. 信号量对象/互斥量对象

    CreateSemaphore();
    ReleaseSemaphore();
    CreateMutex();
    ReleaseMutex();
  11. 线程池

    QueueUserWorkItem();
    SetThreadPriority(HANDLE hPriority, int nPriority); // 进程优先级 + 线程相对优先级
    SetThreadAffinityMask();
    SetProcessAffinityMask();
    GetSystemInfo();
  12. 线程局部存储(TLS,Thread Local Storage)

    • 用于存储线程局部数据
    • 线程之间相互独立
    TlsAlloc(void); // 返回一个 TLS 索引
    TlsSetValue(index, value);
    TlsGetValue(index);
    TlsFree(index);

5 - Linux 进程线程编程

  1. The entry of C programs

    • main function
  2. fork

    • 返回值 0:子进程
  3. 终止一个进程

    • 从 main 中返回
    • 调用 exit
    • 调用 _exit
    • 最后一个线程结束
    • 调用 abort
    • 被信号中断
    • 最后一个线程取消
  4. exit & _exit

    • _exit 是系统调用,立刻停止
    • exit 是库函数
    • exit handler:atexit(function pointer);
  5. wait & waitpid

    pid_t wait(int *status);
    pid_t waitpid(pid_t pid, int *status, int options);
    // paras
    pid == -1; // 同 wait
    pid > 0; // 特定的子进程
    pid == 0; // 任何一个子进程
    pid < 0; // 组号为 n 的有个结束
  6. signal

    signal(signum, handler);
    kill(pid, signal);
    raise(signal);
    // return value
    0 // success
    1 // failure
  7. alarm & pause

    alarm(seconds); // 超时 return 0
    pause(seconds); // 等待 return -1
  8. signal mechanism

    • signal set
    • signal mask
    • signal pending
  9. POSIX thread

    pthread_create(thread, attr, start_index, args);
    pthread_exit(ret_val);
    pthread_join();
    pthread_detach();
    // mutex
    pthread_mutex_init(mutex, attr);
    pthread_mutex_lock(mutex);
    pthread_mutex_unlock(mutex);
    pthread_mutex_destroy(mutex);
    pthread_mutex_trylock(mutex);
    // TLS
    pthread_key_create(key, void);
    pthread_key_delete(key);
    pthread_getspecific(key);
    pthread_setspecific(key, value);

6 - OpenMP

  1. Code Structure

    #include <omp.h>
    #pragma omp parallel
  2. Programming Model

    • 主线程 Master Thread

      omp_set_num_threads(4);
      omp_get_thread_num(); // 1
      #pragma opm parallel
      {
          omp_get_thread_num(); // 4
      }
      #pragma opm parallel num_threads(4)
      {
          omp_get_thread_num(); // 4
      }
  3. 同步

    • critical 临界区

      • 只有一个线程能进入
    • atomic 原子

      • 原子操作
    • barrier

       #pragma omp barrier
       #pragma omp master
       #pragma omp single
    • ordered:顺序执行

  4. for

    #pragma omp parallel
    {
    #pragma omp for
    	for (i = 0; i < N; i++) {
        	// do sth
        } // i is private(i) for each thread
    }
    #pragma omp paraller for
    for (i = 0; i < N; i++) {
        // do sth
    }
  5. Reduction reduction (operation:list)

    #pragma omp parallel for reduction(+:avg)
    for (i = 0; i < N; i++) {
        avg += A[i];
    }
  6. Lock

    omp_init_lock();
    omp_set_lock();
    omp_unset_lock();
    omp_test_lock();
    omp_destroy_lock();
  7. Runtime

    omp_set_num_threads();
    omp_get_num_threads();
    omp_get_thread_num();
    omp_get_max_threads();
    omp_in_parallel();
    omp_num_procs();
    omp_set_dynamic(0);
    omp_get_dynamic();
  8. Data Sharing

    • shared
    • private
      • 对于每个子进程新建一个副本
      • 不初始化
      • 在 Region 外 OpenMP 2.5 是未定义
    • firstprivate
      • 会被初始化
      • 其余同 private
    • default(private|shared|none)
  9. OpenMP 3.0 Tasks

    #pragma omp task     // 例如遍历链表
    #pragma omp taskwait // 例如遍历树
    #pragma omp parallel
    {
    	#pragma omp for private(p)
        for (int i = 0; i < numlists; i++) {
        	p = listheads[i];
            while(p) {
            #pragma omp task
            	process(p);
            p = next(p);
            }
        }
    }
  10. flush

    • barriers
    • entry
    • exit
    • lock
    • atomic entry
  11. OpenMP 3.0

    #pragma omp task untied
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment