![]() |
1
1
我相信线程也遵循优化的规律。
当然,如果系统开始有1000多个核心,那么这个答案可能会过时,需要修改。但是,再次强调,如果你要“完成事情”,那么你肯定想在那之前发货。 |
![]() |
2
9
如果你跟着
管道
和
地图缩小
设计模式,这就足够了。
然后,您可以在实际管道中运行。没有额外的工作。操作系统处理一切。巨大的加速机会。 您也可以切换到线程。做点小工作。操作系统处理其中的一些部分,线程库处理其余部分。但是,由于您在设计时考虑“流程”,所以您的线程没有任何令人困惑的数据共享问题。想一想就大获全胜。 |
![]() |
3
4
引入线程不会自动提高性能。 |
![]() |
4
3
如果你在做一些复杂的多线程的事情,你最好事先考虑一下/设计好它。否则,您的程序将要么是一个完全的灾难,要么会完美地工作。 大多数 做一些疯狂的事情。用多线程设计一个可以证明是正确的东西是很困难的,但是它非常重要。所以不,我不认为好的多线程设计是过早的优化。 |
![]() |
5
2
他们说几天的编码可以节省设计时间。 并非所有的问题和框架都是多线程的。例如,您所依赖的库可能不是线程安全的。许多过程是自然连续的,不能分解成可并行的部分。 多线程/多处理只是并行化的一种方法。例如,您还可以使用异步IO。 在我的经验中,从单个线程进行异步要比从多线程进行异步明智得多。但是,然后,我编写的程序解决了不同的问题,好吧,几乎所有其他人。 |
![]() |
6
1
也许设计系统是件好事 有一些特点 所以如果你想引入多线程 你可以做得很优雅 . 我不确定这些特征是什么,但我想到了一个类似的例子:缩放。如果您设计的是无状态系统可以执行的小型操作,那么您将能够更自然地进行扩展。 在我看来,这类事情似乎很重要。 如果它是为多线程设计的…那么,过早的做法很重要。 如果只是确保某些特性允许将来扩展或多线程:那么它就不那么重要了:) 编辑 哎呀,我又读了一遍:过早优化? 优化:我不认为这是好事,直到你有系统工作(没有来自尝试优化事物的恶习)。做一个干净的设计,这是最灵活和简单的。接下来,您可以在看到真正需要什么时进行优化。 |
![]() |
7
1
我永远不会考虑在应用程序中设计多线程,纯粹是出于推测性的性能考虑。这是因为有了一些适合任何应用程序的技术,很容易在以后进行多线程操作。我想到的技术是:
|
![]() |
8
1
线程的存在使多个代理的使用更容易编程。
换句话说,如果您认为线程==parallelism==performance,那么这只会影响线程的一种用法。 |
![]() |
9
1
有三种基本设计选择:同步、异步或同步+多线程。选择一个或多个,如果你是一个疯狂的天才。 是的,您需要在应用程序的设计阶段了解客户可接受的性能期望,以便能够提前做出正确的选择。对于任何一个不平凡的项目来说,将高级别的性能需求作为事后考虑是非常危险和耗时的。 如果同步不满足客户要求: CPU受限的系统需要选择多线程/进程 IO限制的系统(最常见)通常可以是异步的,也可以是mt。 对于IO,有限的利用技术(如状态线程)可以让您吃蛋糕。(同步设计/w异步执行) |
![]() |
10
0
在实现细节上要放轻松,但要设计出有足够空间优化的设计。现在这是一个棘手的部分,但一旦你习惯了它就没有听起来那么难了。人们发现自己陷入瓶颈设计的一般原因是 太颗粒状 .
因此,作为一个极端的例子,以一个视频处理应用程序为例,它的设计围绕一个抽象的
这样的应用程序在中央设计级别的性能上是拧在一起的,如果没有史诗般的体系结构重写,就不太可能在编辑、编码、解码和回放方面提供有竞争力的性能。这是因为它选择了在一个层次上过于细化的抽象。
通过选择在一个像素级别上进行抽象,这就产生了基于每个像素的动态调度开销。允许虚拟调度、运行时类型信息(反射,例如)等功能的模拟虚拟指针(或语言所使用的任何类型)通常比整个像素本身大,使其内存使用加倍或三倍,并按顺序处理缓存未命中。此外,如果你想事后在许多领域进行多线程的图像处理,你必须重写每一个与之一起工作的地方。
同时,如果软件只是在一个更粗糙的层次上设计抽象,所有这些都可以避免,比如
虽然这看起来像是一个无需大脑的图像处理,它本质上是一个非常关键的性能领域,但在其他领域有很大的空间来实现这一点。对于经典的继承示例,您不必
因此,回到做事情的时候,我以面向数据的心态开始,第一次尝试时不要获得最高效的缓存友好、令人尴尬的并行、线程安全、支持SIMD的数据表示和最先进的数据结构和算法。否则,我可以花整整一周的时间,用手中的vtune来调整东西,同时观察基准测试的速度越来越快(我喜欢这样做,但在任何地方和前面都这样做绝对没有效率)。我只在其中考虑了足够多的内容,以确定设计时应该使用的适当的粒度级别:
“我应该让系统依赖于
数据的大小也会给你一个打击。如果数据很小,比如64字节或更小,那么很可能它不应该公开一个积累依赖关系的接口,除非它绝对不是性能关键的接口。相反,它应该公开一个集合接口来同时处理其中的许多事情。同时,如果数据很大,比如说4千字节,那么很有可能它几乎没有帮助公开一个集合接口,您可能只是为了方便而设计一个标量接口,一次处理其中的一个。 多线程是同样的事情。例如,您不希望锁定在一个级别的粒度太小的地方,也不希望访问模式一直影响共享资源。为了线程安全,您还希望能够获取一段代码,并轻松地解释什么线程正在访问什么状态。要做到这一点,您需要一个更粗糙的设计,其内部具有更同质的处理,这样您就可以轻松地控制和解释设计本身实现中的内存访问模式,最小化对共享资源的访问,避免在某个级别上锁定过细,甚至可能避免直接锁定。只要你的设计留有足够的呼吸空间,你就可以在事后获得很多,但关键是要给自己留有呼吸空间。 一件微小的事情依赖于整个系统中大量不同的事情来进行非均匀的处理,这样就没有空间了。在那里,你可能最终会遇到一个类似赛车的场景,只有10米的道路可以使用。一个庞大的东西,处理一船的青少年东西,它存储同质,留下无限的空间,优化后。 |
|
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |
![]() |
user1700890 · 了解交互式代理Python API中的线程 2 年前 |
![]() |
AntonBoarf · 为什么要将实例变量指定给局部变量? 2 年前 |
![]() |
rhymes · 如何让线程操作相同的java列表 3 年前 |