我有一个2d内存阵列。我有多个线程自发地,任意地和同时地读取和写入数组中的单个元素。
构建内存访问代码的最快方法或最佳做法是什么?我不喜欢锁定的想法,因为它会阻止其他线程。
数据完整性实际上并不重要,但它应该(大多数)是一致的。我的代码可以处理一些内存错误。
它需要非常非常快!
感谢您的反馈。
答案 0 :(得分:2)
如果数据完整性不重要,您只需访问数据而无需关心多线程。
但是,没有人可以预测结果。 但是,我不会称这种方法为“最佳做法”。恕我直言最好的实践是关心多线程,并用适当粒度的互斥锁保护数据。我的观点是每个应用程序应该首先是正确的,然后才是快速的。不一致的结果是错误的,无论它们是否快速都无关紧要。答案 1 :(得分:0)
将Interlocked
类用于CAS(CompareAndExchange
)数组中的对象/值。它使操作原子化,确保数据不被破坏。这是你能做的最快的事情(除了直接访问/修改数据而没有互锁)。但是,如果你正在修改2D数组的大小(增长/缩小),那么除非你在阵列上使用某种锁定机制,否则你会遇到一些严重的问题。
答案 2 :(得分:0)
将数组声明为volatile
并确保它的作用域使得它对所有线程都可见。我通常喜欢避免使用静态,因此要么通过引用传递数组,要么设置所有线程来运行将数组定义为实例字段的实例类的方法。
但是,我强烈建议您重新考虑“易失性访问”在数据完整性方面的含义。如果没有良好的锁定机制,最佳做法是不要做你正在尝试的事情。您可能认为这是一个小问题,但您可能会发现自己的系统非常不确定,以至于其数据在最轻微的情况下都不可靠。
假设您运行了8个线程,并且所有线程都将从数组的索引中获取值,进行一些计算,然后将结果添加回数组的索引。线程1首先启动并获取索引的值0.然后线程2-7全部启动并获得相同的值。线程1执行其计算,再次获取索引以确保它具有“最新”值,然后尝试更新该值。但是,其他线程正在等待该内存,并且由于某些调度实现,您不知道,在线程1获取索引(仍然为零)和写入其结果之间,线程2-7让ALL写入其值。然后线程1写入其值,覆盖其他7个线程所做的所有事情。反过来,其他7个线程可能彼此具有相似的“种族”,因此线程1覆盖的值可能会覆盖一半线程的结果。
我向你保证,这种行为不是你想要的,无论你多么认为你可以逃脱它;它会导致数据损坏,这将影响系统的其他区域,并且您将被迫实施正确的锁定。
答案 3 :(得分:0)
如果您只对性能感兴趣,那么您订购内存访问的方式可以发挥重要作用。花一个小时左右阅读麻省理工学院slides from Lecture 1课程的Performance Engineering。其他讲座也可能对你很有意思(如第6讲)。
基本上,考虑到您正在使用的工作负载,您可以优化缓存的使用,从而大大提高性能,具体取决于您的读/写模式。
但这并不能阻止你做一些正确的事情。