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

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(使用前将#替换为@)

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

  • 获取两个字符串之间的公共部分c# [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要的是获取两个单词之间的共同部分并获取差异 例子 场景1 word1 感言 word2 Test 将返回 公共部分Test 不同之
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它

随机推荐

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

    我在 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