C# 中的基本多线程问题
我是多线程新手,正在研究并行化应用程序中的一个区域。我已经阅读了该网站上的许多帖子,但我仍然对解决问题的最佳方法感到困惑:
[1] In .NET 3.5, is ThreadPool
the only way for a program利用机器中的多核?即是否可以使用 new Thread() 在不同的内核上生成线程?
[2] 我的情况:我有 List
,其中包含大约 80 个项目,当前按顺序处理。因此,考虑到我正在使用 .NET 3.5,并且根据我所读到的内容,由于线程数量较多,ThreadPool
可能是我进行多线程处理的最佳选择,但是:
- 存在很多依赖性之间的计算。目前,该列表的排序方式是所有必需的计算都在开始时执行。
这就是工作项的依赖关系的样子(细节并不重要,只是想强调依赖关系的复杂性):
- 计算时间有很大不同,一个计算对象可能只涉及检索一个值,其他计算对象将涉及嵌套循环中的大量工作......等等
我如何确定主要计算的优先级< /code> 有 10 多个其他工作项目依赖于它?最有效的信号发送方式是什么?
谢谢。
编辑:我应该提到 List
保持不变。然而,计算80+次计算被称为x万次。每次更新迭代器时,都会对列表中的每个Calculation
调用Calculate()。
I'm new to multithreading and I'm working on parallelizing an area in my application. I've read a number of posts on this site but I'm still confused as to the best way to approach my problem:
[1] In .NET 3.5, is ThreadPool
the only way for a program to exploit the multi-cores in the machine ? i.e. Is it possible to spawn threads on different cores using new Thread()
?
[2] My case: I have List<Calculation>
that contains around 80 items, currently processed sequentially. So given that I'm using .NET 3.5 and based on what I've read, ThreadPool
is probably my best bet for multithreading due to the high number of threads, however:
- There is a lot of dependency between the Calculations. Currently, the list is ordered in a way that all required Calculations are performed in the beginning.
This is how the dependency of the work items looks like (details not important, just wanted to make a point on the complexity of the dependencies):
- Calculation times are vastly different, one Calculation object might just involve retrieval of a value , other Calculation objects would involve a lot of work in nested loops...etc
How do I prioritize the main Calculations
that have something like 10+ other work items depending on it ? What is the most efficient way of signaling to use ?
Thank you.
Edit: I should mention that List<Calculation>
remains fixed. However, computing the 80+ calculations is called x million times. Every time an iterator is updated, Calculate() is invoked on every Calculation
in the list.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
[1]:是的,可以使用 new Thread() 在不同的内核上生成线程,尽管使用线程池可能会更好。这里讨论了差异:
线程与线程池
[1]: Yes, it is possible to spawn threads on different cores using
new Thread()
, although you might be better served using the threadpool. The differences are discussed here:Thread vs ThreadPool
在 .Net 4.0 中,使用任务并行库,这会容易得多。
您计划什么时候升级?这可能比您自己编写所有必需的协调代码还要早。
如果您确实必须执行此强力操作,则可以使用 Thread.BeginThreadAffinity 确保封闭的代码在单个 CPU 上运行。这应该有助于您的计算性能。
This would be SO MUCH EASIER in .Net 4.0 using Task Parallel Library.
When are you scheduled to upgrade? It might be sooner than you could write all the required coordinating code yourself.
If you do have to do this brute force, you can use Thread.BeginThreadAffinity to ensure enclosed code runs on a single CPU. This should help your calculation performance.
由操作系统决定线程应该在哪个核心上运行。默认情况下,操作系统会将线程均匀分布在多个内核上(至少在 Windows 中)。
ThreadPool
使用与Thread
类相同类型的线程,因为实际上只有一种线程(但包装它们的类和算法不同类型)使用 ThreadPool.QueueWorkItem 似乎是您转换应用程序的最简单方法。
请记住,运行 100 个不同的线程并不意味着您的应用程序将比运行 10 个线程快 10 倍。如果 .net 和操作系统在线程之间切换时发生后台事务,则 10 个线程更有可能运行得更快。
List
转换为Queue
It's up to the operating system to decide which core a thread should run on. The OS will per default distribute threads evenly over multiple cores (at least in windows).
ThreadPool
are using the same kind of threads as theThread
class, as there really are only one kind (but different types of classes and algorithms wrapping them)Using
ThreadPool.QueueWorkItem
seems to be the easiest way for you to convert your application.Keep in mind that running 100 different threads doesn't say that your application will be 10 times faster than running 10 threads. It's more likely that 10 threads will run faster sine a lot if background stuff happens when .net and the OS switches between threads.
List
into aQueue
正如评论中提到的,PLINQ 使这变得非常简单。
As mentioned in the comments, PLINQ makes this very easy.