有什么方法可以将程序限制在一个CPU上而不关心是哪个CPU吗?
我有一个程序偶尔会出现故障,我想知道问题是否可能与在不同内核上运行的不同线程以不同的顺序处理读取和写入有关(我知道 x86 内存模型需要不同的内核来完成大部分按预期执行的操作,但在某些情况下,读取和写入无法在单个 CPU 上重新排序,但可能在多核系统上重新排序)。将处理器亲和力设置为某些专门选择的任意 CPU 核心似乎不是一个好主意(如果该核心碰巧很忙,则没有理由所有线程都不能迁移到某个其他核心,前提是有完整的缓存先冲水)。有没有什么方法可以简单地指示所有线程必须在同一核心上运行,但我不在乎它是哪一个?
PS--我的理解是,如果一个线程向类实例写入一些数据,然后对类引用执行 CompareExchange(因此该引用将指向新修改的实例),这意味着对实例的所有更改都将在类引用之前写入内存;在使用该类引用的同一 CPU 上的另一个线程上运行的代码将使用类引用的旧值,或者将看到对实例所做的更改;然而,在其他 CPU 上运行的代码在某些棘手的情况下可能会看到类引用的新值,但看不到写入实例的新数据。难道我的理解有误?
I have a program which is occasionally malfunctioning and I'm wondering whether the problems might be related to different threads running on different cores handling reads and writes in a different order (I know the x86 memory model requires different cores to do things mostly as expected, but there are some cases where reads and writes couldn't be resequenced on a single CPU but might on a multi-core system). Setting processor affinity to some specifically-selected arbitrary CPU core doesn't seem like a good idea (if that core happens to be busy, there's no reason all threads shouldn't be able to migrate to some other core, provided there's a full cache flush first). Is there any way to simply direct that all threads must run on the same core, but I don't care which one it is?
PS--My understanding is that if one thread writes some data to a class instance and then does a CompareExchange on a class reference (so the reference will point to the newly-modified instance), that implies that all changes to the instance will be written out to memory before the class reference; code running on another thread on the same CPU which uses that class reference will either use the old value of the class reference or will see the changes that were made to the instance; code running on other CPU's, however, could in some tricky circumstances see the new value of the class reference but not see the new data that was written to the instance. Is my understanding in error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,这也不能解决您的问题。即使在单核上,操作系统也可以随时重新调度您的程序,从而导致相同的问题。您也许能够降低问题发生的可能性 - 但这仅仅意味着当问题不可避免地出现在现场时,调试起来会困难得多。现在就解决你缺乏锁定的问题,以免日后它会咬你一口。
更具体地说,没有 Windows(或 Linux)函数告诉操作系统“将我的所有线程保留在同一核心上”。您可以告诉操作系统将它们全部保留在某个特定核心上,但您不能让它像那样浮动。由于内存屏障相对便宜,因此最好以正确的方式实现它们。即使是锁定操作在现代处理器上也相对便宜 - CPU 在开始操作的读取部分时简单地获得高速缓存行上的锁定(无论如何它必须在任何写入操作中获得锁定)并拒绝释放锁,直到锁定操作完成。
No, and this won't fix your problem either. Even on a single core, the OS can reschedule your program at any time, causing the same problems. You might be able to make the problem less likely to happen - but that just means the problem, when it inevitably appears in the field, will be that much harder to debug. Fix your lack of locking now, before it comes to bite you later.
To be more specific, there is no Windows (or Linux) function that tells the OS, "Keep all my threads on the same core". You can tell the OS to keep them all on some specific core, but you can't leave it floating like that. Since memory barriers are relatively cheap, it's best simply to implement them the right way. Even locked operations are relatively cheap on modern processors - the CPU simply obtains a lock on the cache line when it begins the read part of the operation (which it has to have on any write anyway) and refuses to release the lock until the locked operation is complete.