[已注销]对《多核计算与程序设计》的笔记(8)

多核计算与程序设计
  • 书名: 多核计算与程序设计
  • 作者: 周伟明
  • 页数: 656
  • 出版社: 华中科技大学
  • 出版年: 2009-3
  • 第16页
    在单核CPU和多核CPU上使用多线程的目的不同:前者是为了用户操作和程序的计算(gui编程)可以并行,而后者是为了提供计算性能,把计算分摊到多个核上去
    a、b两个线程可能对不同的内存区域进行操作,但是它们可能共享cache中的同一行,从而引起竞争(事实上同时访问并不会导致数据不一致的问题)。——伪竞争
    2011-11-23 20:00:49 回应
  • 第26页
    线程粒度=线程中有效计算部分(包括锁内计算+锁外计算)/线程因为使用锁而带来的额外开销
    这个系数大,说明线程没有把时间浪费在同步上,因此越大越好。——站在整个线程的角度考虑问题。
    -------------
    锁粒度=锁内计算时间/线程因为使用锁而带来的额外开销
    这个系数越小,引起线程竞争的可能性越小。——站在锁的角度考虑问题
    2011-11-23 21:37:27 回应
  • 第52页
    
    LONG AtomicIncrement(LONG volatile* Target)
    {
        LONG Old;
        do {
            Old = *Target;   //(1)
        } while (!AtomicCAS(Target, Old+1, Old));  //(2)
        return Old;
    }
    
    
    Target指针指向一个共享内存变量,Old是函数AtomicIncrement的一个自动变量
    (1)从共享内存变量中取值作为Old值,如5
    (2)调用AtomicCAS判断此时*Target的内容是否改变
    a.如果未改变还是5,则对它赋值为6
    b.如果改变了,如变成了99,说明之前有其它线程上台修改了*Target,此时不能盲目赋值为6。而是返回(1)重新取*Target的值,直到取完值到调用AtomicCAS这个原子操作之间不再有其它线程修改过*Target时,才进行赋值操作。
    绕个大圈子,本质是因为*Target= *Target + 1不是原子操作
    2011-11-24 15:03:34 回应
  • 第152页
    应为typeof int (* DESTROYFUNC) (void *pData)
    和后面的链表接口中的参数列表保持一致
    定义了一种新的类型DESTROYFUNC,它是一个返回类型为INT,参数列表为void *pData的函数指针。
    因为无类型指针指向内存区域的大小未知,因此无法free,所以这里用一个回调函数,让调用这个接口的代码自己解决释放问题。
    如果调用到这个接口的代码默认的数据类型是int,函数实现就应该这样写:
    int DestroyFunc (void * pData) {
        free((int *)pData);
    }
    
    2011-12-07 21:36:32 回应
  • 第213页
    5,6两章具的两个例子都很实用
    一个是双链表实现的多线程短消息管理队列,一个接收线程接收短消息,一个线程发短消息。
    另一个是用哈希表实现的缓存管理, 定期清除访问不频繁或者驻留时间过长的文件缓存。
    2011-12-09 14:39:11 回应
  • 第326页
    pnMax[k] = nMax;
    
    存在伪共享问题:pnMax很可能存在Cache同一行中,如果多个线程写同一行,将会发生阻塞。
    改进如下:
    #define CACHE_LINE_LEN 64
    
    /* 使相邻两个用来存储数据的单元之间的间隔超过一个CACHE行,这样两个单元就不可能被放到一个CACHE行中 */
    int* pnMax = (int*) malloc (nCore * (sizeof(int) + CACHE_LINE_LEN));
    
    /* 访问数据单元的代码也要改 */
    int pos = k * (sizeof(int) + CACHE_LINE_LEN) / sizeof(int);
    pnMax[pos] = nMax;
    
    
    2012-01-14 20:54:54 回应
  • 第329页
    线程退出通常使用标志位检测的方法
    LONG volatile g_SearchFlag = 0;
    
    ==about volatile
    一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值(From Memory),而不是使用保存在寄存器里的备份。
    下面是volatile变量的几个例子:
    1) 并行设备的硬件寄存器(如:状态寄存器)
    2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
    3) 多线程应用中被几个任务共享的变量
    2012-01-14 22:37:41 回应
  • 第380页
    cache命中率:cache大小为8MB,400*400以下的矩阵运算就不需要考虑cache命中率的问题了
    伪共享:将数组平铺到cache上(保证cache每行只保存数组的一个元素)来避免伪共享问题
    2012-02-05 16:18:22 回应

[已注销]的其他笔记  · · · · · ·  ( 全部295条 )

The Design of Everyday Things
1
About Face 3
6
Engineering a Compiler
1
人有人的用处
8
Understanding the Linux Kernel
4
计算机程序设计艺术
1
公正
1
The Art of Doing Science and Engineering: Learning to Learn
1
科学革命的结构
7
罗素论教育
3
三十六大
1
娱乐至死
3
Real World Haskell
2
Writing Analytically
1
Is Parallel Programming Hard, And, If So, What Can You Do About It?
1
计算机与人脑
1
组合数学
2
菊与刀
1
Rework
5
翻译新究
4
计算机程序的构造和解释(原书第2版)
5
The Laws of Simplicity
4
计算机组成与设计硬件/软件接口
6
写给无神论者
2
放任自流的时光
3
哥德尔、艾舍尔、巴赫
2
树上的男爵
2
C++语言的设计与演化
1
Land of LISP
7
C陷阱与缺陷
2
CUDA by Example
3
C++沉思录
1
世界尽头与冷酷仙境
4
Head First C
2
刀锋
1
并行编程模式
2
The Ph.D. Grind
2
计算机系统结构
2
禅与摩托车维修艺术
14
流浪的面包树
2
翻译研究
18
An Introduction to Programming in Emacs Lisp
1
GNU Emacs Lisp 编程入门
1
计算机系统概论
1
编码
3
拖延心理学
1
古今数学思想(一)
1
挪威的森林
9
奇特的一生
7
GPU高性能运算之CUDA
5
那些年,我们一起追的女孩
8
十八岁给我一个姑娘
2
C++编程思想(第1卷)
9
少有人走的路
5
忧伤的情欲
3
Hackers & Painters
7
哲学的慰藉
9
男人来自火星 女人来自金星
8
旅行的艺术
14
活着活着就老了
1
如何阅读一本书
7
Data-intensive Text Processing With Mapreduce
1
学习GNU Emacs
1
给研究生的学术建议
3
C专家编程
2
Spring揭秘
2
Head First Java(第二版·中文版)
1
自私的基因
1
C程序设计语言
2
计算机网络
3
自由在高处
2
大话设计模式
16
计算机网络
12