为什么在这种无竞争的情况下原子比锁慢得多?

2024-04-17

我使用原子而不是锁编写了一些东西,并且对它在我的情况下慢得多感到困惑,我编写了以下小型测试:

#include <pthread.h>
#include <vector>

struct test
{
    test(size_t size) : index_(0), size_(size), vec2_(size)
        {
            vec_.reserve(size_);
            pthread_mutexattr_init(&attrs_);
            pthread_mutexattr_setpshared(&attrs_, PTHREAD_PROCESS_PRIVATE);
            pthread_mutexattr_settype(&attrs_, PTHREAD_MUTEX_ADAPTIVE_NP);

            pthread_mutex_init(&lock_, &attrs_);
        }

    void lockedPush(int i);
    void atomicPush(int* i);

    size_t              index_;
    size_t              size_;
    std::vector<int>    vec_;
    std::vector<int>    vec2_;
    pthread_mutexattr_t attrs_;
    pthread_mutex_t     lock_;
};

void test::lockedPush(int i)
{
    pthread_mutex_lock(&lock_);
    vec_.push_back(i);
    pthread_mutex_unlock(&lock_);
}

void test::atomicPush(int* i)
{
    int ii       = (int) (i - &vec2_.front());
    size_t index = __sync_fetch_and_add(&index_, 1);
    vec2_[index & (size_ - 1)] = ii;
}

int main(int argc, char** argv)
{
    const size_t N = 1048576;
    test t(N);

//     for (int i = 0; i < N; ++i)
//         t.lockedPush(i);

    for (int i = 0; i < N; ++i)
        t.atomicPush(&i);
}

如果我取消注释atomicPush操作并运行测试time(1)我得到这样的输出:

real    0m0.027s
user    0m0.022s
sys     0m0.005s

如果我运行调用原子事物的循环(看似不必要的操作是因为我希望我的函数看起来尽可能像我更大的代码所做的那样),我会得到如下输出:

real    0m0.046s
user    0m0.043s
sys     0m0.003s

我不确定为什么会发生这种情况,因为在这种情况下我预计原子会比锁更快......

当我使用 -O3 编译时,我看到锁和原子更新如下:

lock:
    real    0m0.024s
    user    0m0.022s
    sys     0m0.001s

atomic:    
    real    0m0.013s
    user    0m0.011s
    sys     0m0.002s

在我较大的应用程序中,尽管锁的性能(单线程测试)仍然做得更好......


无竞争的互斥锁的锁定和解锁速度非常快。有了原子变量,你就可以always付出一定的内存同步代价(特别是因为您甚至没有使用宽松的排序)。

你的测试用例太天真了,没有什么用处。您必须测试竞争激烈的数据访问场景。

一般来说,原子are速度很慢(它们妨碍了巧妙的内部重新排序、流水线和缓存),但它们允许无锁代码,从而确保整个程序可以some进步。相比之下,如果你在持有锁的情况下被换出,everyone必须等待。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在这种无竞争的情况下原子比锁慢得多? 的相关文章

随机推荐

  • 如何使实体框架异步执行

    我在 ASP Net MVC 5 应用程序中遇到异步控制器问题 我正在使用 Entity Framework 6 Code First 方法 我有一个方法 public async Task
  • 如何使用 NPOI 设置 Excel 中的行高?

    如何使用 NPOI 在 C 中设置行高 为了指定列的宽度 我使用 XSSFSheet SetColumnWidth 但是单元格高度的命令是什么样的 尝试下面的方法 var row sheet CreateRow 0 row Height 1
  • 有没有类似 sed 的 cmd.exe 实用程序? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想使用 Windows 命令行以编程方式编辑文件内容 cmd exe http en wikiped
  • C++ 通用链表

    对于下面的代码 include
  • 使用 pip 在 Mac 上安装 Pandas

    我正在尝试安装Pandas with pip 但遇到了问题 详细信息如下 Mac OS Sierra which python gt usr bin python python version gt Python 2 7 10 Inside
  • OpenXml:确定 Excel 中单元格中的图像[重复]

    这个问题在这里已经有答案了 可能的重复 如何检查单元格是否有图片 https stackoverflow com questions 2320826 how to check if a cell has a picture OpenXML
  • 匹配条件时更改列值

    我需要更换一个NULL仅当其他条件匹配时列中的值 Columns Parent Child flag01 lag02 父栏目有很多NULL值 但我想替换null仅当flag01 and flag02是 好的 If flag01 and fl
  • 展平 RDD 中的 Scala 映射

    我有一个 RDD 如下所示 uidProcessedKeywords org apache spark rdd RDD Long Map String Double 如何展平 RDD 中的地图以获得以下结果 org apache spark
  • Flash AS3 - 如何访问其他帧(也称为非一帧)中的显示对象

    只要该子项位于第一帧中 getChildByName name 就会起作用 其他框架中的显示对象还没有被实例化 所以并不是说不能访问它们 它们不存在可供访问的地方 当播放头进入具有特定对象的关键帧时 会创建该对象并将其添加到舞台中 当播放头
  • Python 多线程

    我有这样的场景 使用 Zope Plone 和一些我的 python API 创建的网页 有一个网页 称之为 a 它通过 python 方法调用数据库 Postgres 并返回一些信息 在页面 a 上 您可以 离线 修改数 据库数据 我的意
  • 如何让 CBC 在时限内返回最佳解决方案? (皮莫)

    我正在尝试在 Pyomo 上使用 CBC v2 10 3 来解决整数线性问题 执行求解器时 我当前设置的时间限制为 600 秒 opt SolverFactory cbc opt options seconds 600 在这个时间限制内 求
  • 在Python中跳过范围函数中的值

    循环一系列数字并跳过一个值的Python式方法是什么 例如 范围是从 0 到 100 我想跳过 50 编辑 这是我正在使用的代码 for i in range 0 len list x listRow list i for j in ran
  • BringIntoView 不起作用

    我在事件处理程序后面有这段代码 private void comboActiveStudentAssignmentType SelectionChanged object sender SelectionChangedEventArgs e
  • Faye 在 jruby 的铁轨上

    我搜索了很多 但找不到任何资源表明我可以将 Faye 与 jruby 一起使用 我已经发现this one https groups google com forum fromgroups topic faye users wvp K38v
  • 在资源路径中找不到 com/sun/jna/android-arm/libjnidispatch.so

    以下所有操作均在 Android Studio 中完成 我已成功编译并测试了 Android Watson Speech to Text 演示应用程序 然后 我创建了一个包含 Watson 相关 API 的库项目和一个带有引用 Watson
  • 如何向 Next.js 静态站点添加网站图标?

    我正在尝试将网站图标添加到 Next js 静态站点 但运气不佳 我尝试使用以下组件自定义文档 next document https nextjs org docs custom document https nextjs org doc
  • 如何连接字符串列表? [复制]

    这个问题在这里已经有答案了 对于你们大多数人来说 这可能非常容易解决 但我无法简单地解决这个问题str 周围可以吗 我想转换这个列表 A B C into A B C In 1 L A B C In 2 join L Out 2 A B C
  • Apache 中的手动内容压缩

    我需要 Apache 上的手动压缩解决方案 我的目标 在我的服务器上提供 gzip 编码的内容以及未压缩的内容 文件已预先压缩 并非所有文件都经过压缩 我想指定这些文件 并且选择不是基于类型 扩展名 的 提供许多内容类型 自定义内容类型 并
  • NuGet 不更新项目引用

    我最近将所有 Visual Studio 2013 项目迁移到 Visual Studio 2015 并按照本文档中记录的步骤进行操作article https docs nuget org consume package restore
  • 为什么在这种无竞争的情况下原子比锁慢得多?

    我使用原子而不是锁编写了一些东西 并且对它在我的情况下慢得多感到困惑 我编写了以下小型测试 include