.NET:线程的开销
假设我有两个线程:A和B。当A创建一个对象(例如字符串列表)并将其传递给B进行处理时。每次 B 访问这个对象时,性能会下降吗?或者当对象从 A 编组到 B 时是否会受到一次性处罚?
Suppose I have two threads: A and B. When A creates an object(for example a List of String), and passes it to B for processing. Will there a performance decrease for each time B access this object? Or will there be a one-time penalty while the object is marshalled from A to B?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
仅仅因为您在 .Net 中使用多线程并不意味着将使用封送处理。当您跨 AppDomain 共享对象时,封送处理就会发挥作用。
假设没有 AppDomain,那么您将付出的开销将是锁定 - 确保一次只有一个线程访问该对象。每次锁定和解锁一个对象都会占用一些 CPU 周期。
使用多个线程还会增加其他惩罚 - 例如,如果您必须从线程 A 交换到线程 B 才能完成某些任务,那么可能会存在线程切换的惩罚。如果 CPU 必须让线程 A 休眠并唤醒线程 B,那么将花费一些处理器周期来执行此操作。即使线程 A 和线程 B 运行在不同的 CPU 上但修改公共数据,那么 CPU 缓存中的数据也可能必须被丢弃(缓存晃动)。只是警告您可能会尝试通过并行处理来加快速度,但最终会减慢应用程序的速度。
如果您要从另一个 .Net AppDomain 访问在一个 .Net AppDomain 中创建的对象,则将使用封送处理。并且,根据您使用的封送类型,您可以选择一次性惩罚(按值封送)或每次调用惩罚(按引用封送)。
Just because you are using multiple threads in .Net does not imply marshaling will be used. Marshaling comes into play when you are sharing objects across AppDomains.
Assuming there are no AppDomains then the overhead you would pay would be locking - making sure only one thread accesses the object at a time. Each time you lock and unlock an object it will take up some CPU cycles.
Using multiple threads can also add other penalties - for example if you have to swap from thread A to thread B to complete some task then there may be the penalty of a thread switch. If the CPU has to put thread A to bed and wake up thread B then there will be some processor cycles spent doing this. Even if thread A and thread B are running on different CPUs but modifying common data then data in the CPU caches may have to be discarded (cache sloshing). Just a warning that you might try to speed something up by processing in parallel but end up slowing your app down.
Marshaling would be used if you are accessing an object created in one .Net AppDomain from another. And, depending on the type of marshaling you are using you could either go for the one time penalty (marshal by value) or the per call penalty (marshal by reference).
.NET 中的线程之间没有编组。两个线程将与相同的内存进行交互,以存储与对象关联的存储。让一个线程而不是另一个线程对对象执行操作不会产生性能开销。
您需要担心线程之间的同步以确保线程安全,而不是性能。
There is no marshalling between threads in .NET. Both threads will interact with the same memory for storage associated with the object. There is no performance overhead for having one thread rather than another perform an operation on the object.
You need to worry about synchronisation between threads to ensure thread safety, not performance.
线程位于相同的内存空间中,因此没有编组,也没有访问对象的惩罚。
然而,由于它们共享内存,您必须同步对对象的访问,以便一次只能由一个线程访问任何已更改的内容。当一个线程访问一个对象时,另一个线程必须等待,这会导致一些开销。
The threads live in the same memory space, so there is no marshalling, and no penalty for accessing objects.
However, as they share the memory you have to synchronise the access to the objects so that anything that is ever changed is only accessed by one thread at a time. When one thread is accessing an object the other thread has to wait, so that will cause a bit of overhead.