I have built an application in C# that I would like to be optimized for multiple cores. I have some threads, should I do more?
我在C#中构建了一个应用程序,我希望针对多个内核进行优化。我有一些线程,我应该做更多吗?
Updated for more detail
更新了更多细节
- C# 2.0
- Run on Windows Vista and Windows Server 2003
在Windows Vista和Windows Server 2003上运行
Updated again
- This code is running as a service
- I do not want to have the complete code... my goal here is to get your experience and how to start. Like I say, I have already use threads. What more can I do?
此代码作为服务运行
我不想拥有完整的代码......我的目标是获得您的经验以及如何开始。就像我说的,我已经使用过线程。我还能做什么?
6 个解决方案
#1
46
I'd generalize that writing a highly optimized multi-threaded process is a lot harder than just throwing some threads in the mix.
我总结一下,编写高度优化的多线程进程要比在混合中抛出一些线程要困难得多。
I recommend starting with the following steps:
我建议从以下步骤开始:
- Split up your workloads into discrete parallel executable units
- Measure and characterize workload types - Network intensive, I/O intensive, CPU intensive etc - these become the basis for your worker pooling strategies. e.g. you can have pretty large pools of workers for network intensive applications, but it doesn't make sense having more workers than hardware-threads for CPU intensive tasks.
- Think about queuing/array or ThreadWorkerPool to manage pools of threads. Former more finegrain controlled than latter.
- Learn to prefer async I/O patterns over sync patterns if you can - frees more CPU time to perform other tasks.
- Work to eliminate or atleast reduce serialization around contended resources such as disk.
- Minimize I/O, acquire and hold minimum level of locks for minimum period possible. (Reader/Writer locks are your friend)
5.Comb through that code to ensure that resources are locked in consistent sequence to minimize deadly embrace. - Test like crazy - race conditions and bugs in multithreaded applications are hellish to troubleshoot - often you only see the forensic aftermath of the *.
将工作负载拆分为离散的并行可执行单元
衡量和表征工作负载类型 - 网络密集型,I / O密集型,CPU密集型等 - 这些成为您的工作池合并策略的基础。例如对于网络密集型应用程序,您可以拥有相当大的工作池,但对于CPU密集型任务而言,拥有更多工作者而不是硬件线程是没有意义的。
考虑排队/数组或ThreadWorkerPool来管理线程池。前者比后者控制更细粒度。
如果可以的话,学习优先于同步模式的异步I / O模式 - 释放更多的CPU时间来执行其他任务。
努力消除或至少减少围绕竞争资源(如磁盘)的序列化。
最小化I / O,获取并保持最低级别的锁定,以尽可能减少时间。 (读者/作者锁是你的朋友)5。通过该代码来确保资源以一致的顺序锁定,以最大限度地减少致命的拥抱。
像疯了似的测试 - 多线程应用程序中的竞争条件和错误是排除故障的地狱 - 通常你只能看到大*的法医后果。
Bear in mind that it is entirely possible that a multi-threaded version could perform worse than a single-threaded version of the same app. There is no excuse for good engineering measurement.
请记住,多线程版本完全有可能比同一个应用程序的单线程版本更糟糕。良好的工程测量没有任何借口。
#2
8
You might want to take a look at the parallel extensions for .NET
您可能想看一下.NET的并行扩展
#3
8
You might want to read Herb Sutter's column 'Effective Concurrency'. You'll find those articles here, with others.
您可能想阅读Herb Sutter的专栏“Effective Concurrency”。你会在这里和其他人一起找到这些文章。
#4
6
To be able to utilize multiple cores more efficiently you should divide your work up in parts that can be executed in parallel and use threads to divide the work over the cores. You could use threads, background workers, thread pools, etc
为了能够更有效地利用多个内核,您应该将您的工作划分为可以并行执行的部分,并使用线程将工作分配到内核上。您可以使用线程,后台工作程序,线程池等
#5
5
For C#, start learning the LINQ-way of doing things, then make use of the Parallel LINQ library and its .AsParallel() extension.
对于C#,开始学习LINQ方式,然后使用Parallel LINQ库及其.AsParallel()扩展。
#6
2
Understanding the parallelism (or potential for parallelism) in the problem(s) you are trying to solve, your application and its algorithms is much more important than any details of thread synchronization, libraries, etc.
了解您尝试解决的问题中的并行性(或并行性的可能性),您的应用程序及其算法比线程同步,库等的任何细节都重要得多。
Start by reading Patterns for Parallel Programming (which focuses on 'finding concurrency' and higher-level design issues), and then move on to The Art of Multiprocessor Programming (practical details starting from a theoretical basis).
首先阅读并行编程模式(主要关注'发现并发'和更高级别的设计问题),然后转到多处理器编程的艺术(实际细节从理论基础开始)。
#1
46
I'd generalize that writing a highly optimized multi-threaded process is a lot harder than just throwing some threads in the mix.
我总结一下,编写高度优化的多线程进程要比在混合中抛出一些线程要困难得多。
I recommend starting with the following steps:
我建议从以下步骤开始:
- Split up your workloads into discrete parallel executable units
- Measure and characterize workload types - Network intensive, I/O intensive, CPU intensive etc - these become the basis for your worker pooling strategies. e.g. you can have pretty large pools of workers for network intensive applications, but it doesn't make sense having more workers than hardware-threads for CPU intensive tasks.
- Think about queuing/array or ThreadWorkerPool to manage pools of threads. Former more finegrain controlled than latter.
- Learn to prefer async I/O patterns over sync patterns if you can - frees more CPU time to perform other tasks.
- Work to eliminate or atleast reduce serialization around contended resources such as disk.
- Minimize I/O, acquire and hold minimum level of locks for minimum period possible. (Reader/Writer locks are your friend)
5.Comb through that code to ensure that resources are locked in consistent sequence to minimize deadly embrace. - Test like crazy - race conditions and bugs in multithreaded applications are hellish to troubleshoot - often you only see the forensic aftermath of the *.
将工作负载拆分为离散的并行可执行单元
衡量和表征工作负载类型 - 网络密集型,I / O密集型,CPU密集型等 - 这些成为您的工作池合并策略的基础。例如对于网络密集型应用程序,您可以拥有相当大的工作池,但对于CPU密集型任务而言,拥有更多工作者而不是硬件线程是没有意义的。
考虑排队/数组或ThreadWorkerPool来管理线程池。前者比后者控制更细粒度。
如果可以的话,学习优先于同步模式的异步I / O模式 - 释放更多的CPU时间来执行其他任务。
努力消除或至少减少围绕竞争资源(如磁盘)的序列化。
最小化I / O,获取并保持最低级别的锁定,以尽可能减少时间。 (读者/作者锁是你的朋友)5。通过该代码来确保资源以一致的顺序锁定,以最大限度地减少致命的拥抱。
像疯了似的测试 - 多线程应用程序中的竞争条件和错误是排除故障的地狱 - 通常你只能看到大*的法医后果。
Bear in mind that it is entirely possible that a multi-threaded version could perform worse than a single-threaded version of the same app. There is no excuse for good engineering measurement.
请记住,多线程版本完全有可能比同一个应用程序的单线程版本更糟糕。良好的工程测量没有任何借口。
#2
8
You might want to take a look at the parallel extensions for .NET
您可能想看一下.NET的并行扩展
#3
8
You might want to read Herb Sutter's column 'Effective Concurrency'. You'll find those articles here, with others.
您可能想阅读Herb Sutter的专栏“Effective Concurrency”。你会在这里和其他人一起找到这些文章。
#4
6
To be able to utilize multiple cores more efficiently you should divide your work up in parts that can be executed in parallel and use threads to divide the work over the cores. You could use threads, background workers, thread pools, etc
为了能够更有效地利用多个内核,您应该将您的工作划分为可以并行执行的部分,并使用线程将工作分配到内核上。您可以使用线程,后台工作程序,线程池等
#5
5
For C#, start learning the LINQ-way of doing things, then make use of the Parallel LINQ library and its .AsParallel() extension.
对于C#,开始学习LINQ方式,然后使用Parallel LINQ库及其.AsParallel()扩展。
#6
2
Understanding the parallelism (or potential for parallelism) in the problem(s) you are trying to solve, your application and its algorithms is much more important than any details of thread synchronization, libraries, etc.
了解您尝试解决的问题中的并行性(或并行性的可能性),您的应用程序及其算法比线程同步,库等的任何细节都重要得多。
Start by reading Patterns for Parallel Programming (which focuses on 'finding concurrency' and higher-level design issues), and then move on to The Art of Multiprocessor Programming (practical details starting from a theoretical basis).
首先阅读并行编程模式(主要关注'发现并发'和更高级别的设计问题),然后转到多处理器编程的艺术(实际细节从理论基础开始)。