问个猪一般的问题:为何多线程编程不能对for 循环提速

m
microsat
楼主 (北美华人网)
一个for循环 i=0; //下面采用多线程编程 for(int i; i<1000; i++) a = b + c; }
发现:计算时间并没有任何减少。
请问这是为什么?
c
coalpilerd
从这段伪代码我看不到多线程啊,你是create了几个线程,把这个for循环拆开了分到那几个线程上吗?
m
mRNA
我猜都是往a变量里写,同变量的写操作不能并行
t
ted.hanks
你这段代码碰到牛逼的编译器,直接就变成a = b + c。 如果b, c 不是volatile 的话。
n
nicecool
需要用thread safe的数据结构。必要的话还要处理一下结果。
m
magicxxxxx
回复 1楼microsat的帖子
光看你写的例子,b,c都是循环不变的,循环相关的可以直接被删除 你可以看下.s文件,程序最后优化成啥样了
熊熊ABC
你是每个thread 都跑一千次还是每次随机叫醒一个thread做加法?
w
wdong
一个for循环 i=0; //下面采用多线程编程 for(int i; i<1000; i++) a = b + c; }
发现:计算时间并没有任何减少。
请问这是为什么?
microsat 发表于 2022-01-04 17:01

你用openmp就可以提速了。前面加一行 #pragma omp parallel for 不过需要循环次数很多才能感觉出来加速。
张国荣
谁说的???
g
gokgs
我严重怀疑楼主刚开始接触多线程,连什么是thread 都还没搞清楚。哈哈。
m
microsat
你用openmp就可以提速了。前面加一行 #pragma omp parallel for 不过需要循环次数很多才能感觉出来加速。
wdong 发表于 2022-01-04 17:16

提不了速度。因为这是硬循环。 假设4个线程。每个线程做250个循环,总共1000个循环。
如果1个线程,需要运算的循环数是1000. 如果是4个线程,每个线程运算250个循环,总共还是要运算1000个循环。
因为机器是单cpu,所以4个线程都在这个cpu里运行。所以速度不能提高。
i
iheartnyc
一个for循环 i=0; //下面采用多线程编程 for(int i; i<1000; i++) a = b + c; }
发现:计算时间并没有任何减少。
请问这是为什么?
microsat 发表于 2022-01-04 17:01

多线程也需要你把工作量分成小块啊。如果你有1000块砖,一个工人搬需要一天,你雇了10个狗工人,但是9个不干活,还是只有一个人搬1000块砖,当然不会节省时间。
你这段code如果仅仅加入多线程,没有别的改变,那就是每个线程都loop了1000次,如果增加N个线程,相当于工作量增加了N倍。
m
microsat
多线程也需要你把工作量分成小块啊。如果你有1000块砖,一个工人搬需要一天,你雇了10个狗工人,但是9个不干活,还是只有一个人搬1000块砖,当然不会节省时间。
你这段code如果仅仅加入多线程,没有别的改变,那就是每个线程都loop了1000次,如果增加N个线程,相当于工作量增加了N倍。
iheartnyc 发表于 2022-01-04 17:24

我的意思是把一个1000个循环次数的程序段落,分给4个线程,每个线程循环250次,来完成。
结果,计算时间没变。
M
Moscow79
回复 13楼microsat的帖子
那肯定是有race condition,仔细检查一下是不是所有线程都在访问同一块公共变量
t
ted.hanks
profiling啊, 看看阻塞在什么地方。 Show me the code
M
Moscow79
回复 14楼Moscow79的帖子
或者就是你的硬件只有一个core??
m
microsat
回复 13楼microsat的帖子
我的说的意思,其实下面这个例子。
假设你的电脑挂载了5个分区。A,B,C,D,E 把A,B,C,D的内容全部拷贝到E。
你如果开4个线程,一个线程拷贝A到E,第4个线程拷贝D到E。 结果,你发现,时间上和你用一个线程一点没省。 因为你的cpu只有1个。
m
microsat
回复 14楼Moscow79的帖子
或者就是你的硬件只有一个core??
Moscow79 发表于 2022-01-04 17:30

对。老式的单cpu的机器。
M
Moscow79
回复 18楼microsat的帖子
那当然不能提速啊!因为还是同一个cpu轮流执行这几个thread。多线程加速是针对很多个核的CPU来说的!
c
coalpilerd
对。老式的单cpu的机器。
microsat 发表于 2022-01-04 17:32

我去,单CPU提毛速,再多的线程也还是只能用那一个CPU,各线程没法并行啊。
m
microsat
回复 18楼microsat的帖子
那当然不能提速啊!因为还是同一个cpu轮流执行这几个thread。多线程加速是针对很多个核的CPU来说的!
Moscow79 发表于 2022-01-04 17:34

我可以这么认为吗? 如果cpu只有2个,那么开大于2个的线程,和2个线程是一样的计算时间。
比如n_thread =3, 和n_thread=2是一样的计算时间,因为cpu只有2个。
b
badgerbadger
你这段代码碰到牛逼的编译器,直接就变成a = b + c。 如果b, c 不是volatile 的话。
ted.hanks 发表于 2022-01-04 17:08

re…lz了解一下LICM
不,lz先了解一下OS,memory structure,和kernel吧。学一学assembly,看看编译器是怎么把你的code变成assembly的,还有各种运算/读写的耗时。
我们这样帮忙是治标不治本。
c
coalpilerd
我可以这么认为吗? 如果cpu只有2个,那么开大于2个的线程,和2个线程是一样的计算时间。
比如n_thread =3, 和n_thread=2是一样的计算时间,因为cpu只有2个。
microsat 发表于 2022-01-04 17:37

……搞不好还不如俩线程。如果你能保证俩线程各占一个CPU从头跑到尾的话。各线程之间context switch那也是时间成本。
r
reed7
如果你的 for 循环里面都是 CPU intense 的操作,机器又只有一个 CPU,强行搞多线程不仅有可能对程序执行速度没帮助,还可能还会适得其反)