相关疑难解决方法(0)

为什么Interlocked.Add没有超载接受双打作为参数?

我完全理解Threading.Interlocked类提供的原子性; 但是,我不明白为什么Add函数只提供两个重载:一个用于Integers,另一个用于Longs.为什么不双打,或任何其他数字类型?

显然,更改Double的预期方法是CompareExchange; 我认为这是因为修改Double比修改Integer更复杂.我还不清楚为什么,如果CompareExchange和Add都能接受整数,他们也不能同时接受双打.

.net c# vb.net multithreading atomic

20
推荐指数
3
解决办法
7463
查看次数

为什么这段代码不能证明读/写的非原子性?

阅读 这个问题,我想测试一下我是否可以证明对这种操作的原子性无法保证的类型的读写非原子性.

private static double _d;

[STAThread]
static void Main()
{
    new Thread(KeepMutating).Start();
    KeepReading();
}

private static void KeepReading()
{
    while (true)
    {
        double dCopy = _d;

        // In release: if (...) throw ...
        Debug.Assert(dCopy == 0D || dCopy == double.MaxValue); // Never fails
    }
}

private static void KeepMutating()
{
    Random rand = new Random();
    while (true)
    {
        _d = rand.Next(2) == 0 ? 0D : double.MaxValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,即使在执行了整整三分钟之后,断言也拒绝失败.是什么赋予了?

  1. 测试不正确.
  2. 测试的具体时序特性使得断言不太可能/不可能失败.
  3. 概率是如此之低,以至于我必须运行测试更长时间以使其可能会触发.
  4. 与C#规范相比,CLR提供了更强的原子性保证.
  5. 我的OS /硬件提供比CLR更强的保证.
  6. 别的什么?

当然,我不打算依赖规范没有明确保证的任何行为,但我想更深入地了解这个问题. …

.net c# double atomic thread-safety

11
推荐指数
1
解决办法
718
查看次数

为什么需要内存对齐?

我知道这个问题已经被问了一千次,我已经通读了每一个答案,但我仍然不明白。我的 RAM 模型可能存在一些基本错误,这使我无法理解任何答案。

我从互联网上获得了所有这些小信息,但我无法连接它们。

以下是我目前所知道的:以 IA-32 架构为例,其字边界为 32 位(边界 = CPU 可以从内存中读取的最大值?)。它将始终在其字边界内读取。

1)那么,无论我给它什么地址,它总是会读取 4 个字节?如果我在地址 x 有一个简单的字符怎么办。它会从那个地址读取 4 个字节,然后做一些奇怪的事情来只得到一个字节吗?

2)如果是这样,那么字符串(字符序列)n_chars * 4 字节大吗?我很确定它不是那样的,但是我应该如何解释“将始终阅读其单词边界”呢?

3)内存对齐似乎只与数据结构有关。为什么?内存的其余部分是否未对齐?我的意思是物理、虚拟、内核空间等?

4) 为什么我只能在可被 4 整除的地址中存储 32 位值?我的意思是我知道它最终只会读取 32 位,但为什么它不能从奇数地址读取 32 位?比如这里的限制是什么?

我只是很困惑请帮助我

memory x86 assembly memory-alignment low-level

2
推荐指数
1
解决办法
1839
查看次数