当前位置: 首页 > news >正文

麻涌做网站/少儿培训

麻涌做网站,少儿培训,个人备案域名可以做哪些网站,天津专业制作企业官网给分支预测器的建议 原始代码 以下代码用于实现多线程中只调用一次的效果&#xff0c;这里的if大多数情况下都是false&#xff0c;即已经被调用过了。这里是否被调用过用的是一个std::atomic<uint32_t>的原子变量 template <typename Callable, typename... Args>…

给分支预测器的建议

原始代码

以下代码用于实现多线程中只调用一次的效果,这里的if大多数情况下都是false,即已经被调用过了。这里是否被调用过用的是一个`std::atomic<uint32_t>`的原子变量
template <typename Callable, typename... Args>
void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) {std::atomic<uint32_t>* once = base_internal::ControlWord(&flag);uint32_t s = once->load(std::memory_order_acquire);if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) {base_internal::CallOnceImpl(once, base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL,std::forward<Callable>(fn), std::forward<Args>(args)...);}
}

用于做分支预测建议的宏

// Recommendation: Modern CPUs dynamically predict branch execution paths,
// typically with accuracy greater than 97%. As a result, annotating every
// branch in a codebase is likely counterproductive; however, annotating
// specific branches that are both hot and consistently mispredicted is likely
// to yield performance improvements.
#if ABSL_HAVE_BUILTIN(__builtin_expect) || \(defined(__GNUC__) && !defined(__clang__))
#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
#else
#define ABSL_PREDICT_FALSE(x) (x)
#define ABSL_PREDICT_TRUE(x) (x)
#endif

解释

(__builtin_expect(false || (x), true)) 是一个使用了 GCC 内置函数 __builtin_expect 的表达式。这个内置函数通常用于向编译器提供分支预测信息,以优化代码的执行。

__builtin_expect 函数的语法是:

__builtin_expect(EXPRESSION, EXPECTED_VALUE)
  • EXPRESSION 是一个表达式,可以是任何布尔表达式。
  • EXPECTED_VALUE 是一个编译器期望表达式 EXPRESSION 的结果为真或假的值。通常使用 truefalse

__builtin_expect 函数告诉编译器表达式 EXPRESSION 的结果很可能是 EXPECTED_VALUE,以便编译器对代码进行优化。这种优化涉及到对条件分支的预测,使得最有可能的分支能够更快地执行,提高代码的性能。

在你的表达式中,(__builtin_expect(false || (x), true)) 使用了 __builtin_expect 函数,期望 (false || (x)) 的结果为真。这样的编码风格通常用于告诉编译器,(false || (x)) 表达式中的 x 很可能为真,以便编译器在生成机器代码时进行相关的优化。

需要注意的是,__builtin_expect 是 GCC 提供的特定于编译器的内置函数,因此它在其他编译器或开发环境中可能不可用。如果你的代码需要在其他编译器中编译,可能需要进行适当的修改或条件编译。

其他

讲讲这个call_once在面对多线程竞争时的实现原理。

  1. 第一个进入的线程可以执行
  2. 后续进入的线程需要等待
    有了这个认识,剩下的就是看原子变量的改变过程和等待过程了。

template <typename Callable, typename... Args>
ABSL_ATTRIBUTE_NOINLINE
void CallOnceImpl(std::atomic<uint32_t>* control,base_internal::SchedulingMode scheduling_mode, Callable&& fn,Args&&... args) {static const base_internal::SpinLockWaitTransition trans[] = {{kOnceInit, kOnceRunning, true},{kOnceRunning, kOnceWaiter, false},{kOnceDone, kOnceDone, true}};// Must do this before potentially modifying control word's state.base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode);// Short circuit the simplest case to avoid procedure call overhead.// The base_internal::SpinLockWait() call returns either kOnceInit or// kOnceDone. If it returns kOnceDone, it must have loaded the control word// with std::memory_order_acquire and seen a value of kOnceDone.uint32_t old_control = kOnceInit;if (control->compare_exchange_strong(old_control, kOnceRunning,std::memory_order_relaxed) ||base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans,scheduling_mode) == kOnceInit) {base_internal::invoke(std::forward<Callable>(fn),std::forward<Args>(args)...);old_control =control->exchange(base_internal::kOnceDone, std::memory_order_release);if (old_control == base_internal::kOnceWaiter) {base_internal::SpinLockWake(control, true);}}  // else *control is already kOnceDone
}
// See spinlock_wait.h for spec.
uint32_t SpinLockWait(std::atomic<uint32_t> *w, int n,const SpinLockWaitTransition trans[],base_internal::SchedulingMode scheduling_mode) {int loop = 0;for (;;) {uint32_t v = w->load(std::memory_order_acquire);int i;for (i = 0; i != n && v != trans[i].from; i++) {}if (i == n) {SpinLockDelay(w, v, ++loop, scheduling_mode);  // no matching transition} else if (trans[i].to == v ||                   // null transitionw->compare_exchange_strong(v, trans[i].to,std::memory_order_acquire,std::memory_order_relaxed)) {if (trans[i].done) return v;}}
}

这里精彩的地方有两个,一个是多线程进入时候的状态机转换过程,即原子变量遵循的trans数组。第二个是SpinLockDelay在多个平台下的实现。

//posix linux 
ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop,absl::base_internal::SchedulingMode /* mode */) {absl::base_internal::ErrnoSaver errno_saver;if (loop == 0) {} else if (loop == 1) {sched_yield();} else {struct timespec tm;tm.tv_sec = 0;tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop);nanosleep(&tm, nullptr);}
}
//win32
void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop,absl::base_internal::SchedulingMode /* mode */) {if (loop == 0) {} else if (loop == 1) {Sleep(0);} else {// SpinLockSuggestedDelayNS() always returns a positive integer, so this// static_cast is safe.Sleep(static_cast<DWORD>(absl::base_internal::SpinLockSuggestedDelayNS(loop) / 1000000));}
}
//sleep ms consideration
// Return a suggested delay in nanoseconds for iteration number "loop"
int SpinLockSuggestedDelayNS(int loop) {// Weak pseudo-random number generator to get some spread between threads// when many are spinning.uint64_t r = delay_rand.load(std::memory_order_relaxed);r = 0x5deece66dLL * r + 0xb;   // numbers from nrand48()delay_rand.store(r, std::memory_order_relaxed);if (loop < 0 || loop > 32) {   // limit loop to 0..32loop = 32;}const int kMinDelay = 128 << 10;  // 128us// Double delay every 8 iterations, up to 16x (2ms).int delay = kMinDelay << (loop / 8);// Randomize in delay..2*delay range, for resulting 128us..4ms range.return delay | ((delay - 1) & static_cast<int>(r));
}

L1数据预取

abseil里面还定义了三个函数用于数据预取(prefetch)到本地缓存的函数。

数据预取是一种优化技术,通过提前将数据移动到CPU的缓存中,以便在数据被使用之前加速访问。这些函数的作用是将指定地址的数据预取到L1缓存中,以便在读取数据之前移动数据到缓存中。这样,当读取发生时,数据可能已经在缓存中,以提高访问速度。

下面是这些函数的简要说明:

  1. void PrefetchToLocalCache(const void* addr): 将数据预取到L1缓存中,具有最高程度的时间局部性(temporal locality)。在可能的情况下,数据将预取到所有级别的缓存中。这个函数适用于具有长期重复访问的数据。

  2. void PrefetchToLocalCacheNta(const void* addr): 与PrefetchToLocalCache函数相同,但具有非时间局部性(non-temporal locality)。这意味着预取的数据不应该留在任何缓存层级中。这在数据只使用一次或短期使用的情况下很有用,例如对对象调用析构函数。

  3. void PrefetchToLocalCacheForWrite(const void* addr): 将具有修改意图的数据预取到L1缓存中。这个函数类似于PrefetchToLocalCache,但会预取带有“修改意图”的缓存行。通常包括在所有其他缓存层级中使该地址的缓存条目无效,并具有独占访问意图。这个函数用于在修改数据之前将数据预取到缓存中。

这些函数需要注意的是,不正确或滥用使用这些函数可能会降低性能。只有在经过充分的基准测试表明有改进时,才应使用这些函数。

ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache(const void* addr) {_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0);
}ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta(const void* addr) {_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_NTA);
}ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite(const void* addr) {
#if defined(_MM_HINT_ET0)_mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_ET0);
#elif !defined(_MSC_VER) && defined(__x86_64__)// _MM_HINT_ET0 is not universally supported. As we commented further// up, PREFETCHW is recognized as a no-op on older Intel processors// and has been present on AMD processors since the K6-2. We have this// disabled for MSVC compilers as this miscompiles on older MSVC compilers.asm("prefetchw (%0)" : : "r"(addr));
#endif
}

编译器静态检查

#if ABSL_HAVE_ATTRIBUTE(guarded_by)
#define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x)))
#else
#define ABSL_GUARDED_BY(x)
#endif

__attribute__((guarded_by(x))) 是一个GCC/Clang的扩展属性(attribute),用于指定一个互斥量(mutex)或锁(lock)来保护变量的访问。

这个属性的语法如下:

__attribute__((guarded_by(x)))

其中,x 是一个标识符,用于指定用于保护变量访问的互斥量或锁的名称。

该属性的作用是向编译器提供关于变量的额外信息,以帮助进行静态分析和检查多线程代码中的数据竞争问题。通过将 __attribute__((guarded_by(x))) 应用于变量,我们可以指示编译器该变量受特定互斥量的保护,从而在编译时进行检查。

例如,考虑以下示例:

#include <mutex>std::mutex mutex;
int shared_data __attribute__((guarded_by(mutex)));void foo()
{std::lock_guard<std::mutex> lock(mutex);// 访问 shared_datashared_data = 42;
}

在上面的示例中,shared_data 变量被 guarded_by 属性修饰,指示它受 mutex 互斥量的保护。这样,当在没有获取 mutex 互斥量的情况下访问 shared_data 时,编译器会发出警告或错误,以帮助检测潜在的数据竞争问题。

需要注意的是,__attribute__((guarded_by(x))) 是GCC/Clang的扩展属性,不是标准C++的一部分。因此,它在不同编译器之间可能具有不同的行为或不受支持。在使用该属性时,应注意编译器的兼容性和文档。

相关文章:

abseil中的微操

给分支预测器的建议 原始代码 以下代码用于实现多线程中只调用一次的效果&#xff0c;这里的if大多数情况下都是false&#xff0c;即已经被调用过了。这里是否被调用过用的是一个std::atomic<uint32_t>的原子变量 template <typename Callable, typename... Args>…...

NLP论文阅读记录 - 2022 | WOS 数据驱动的英文文本摘要抽取模型的构建与应用

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结 前言 Construction and Application of a Data-Driven Abstract Extractio…...

虹科新闻丨LIBERO医药冷链PDF温度计完成2024年航空安全鉴定,可安全空运!

来源&#xff1a;虹科环境监测技术 虹科新闻丨LIBERO医药冷链PDF温度计完成2024年航空安全鉴定&#xff0c;可安全空运&#xff01; 原文链接&#xff1a;https://mp.weixin.qq.com/s/XHT4kU27opeKJneYO0WqrA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 虹科LIBE…...

智能搬运机器人作为一种新型的物流技术

随着物流行业的快速发展&#xff0c;货物转运的效率和准确性成为了企业竞争的关键因素之一。智能搬运机器人作为一种新型的物流技术&#xff0c;已经在许多企业中得到了广泛应用。本文将介绍富唯智能智能搬运机器人在物流行业的应用和优势。 在实际应用中&#xff0c;智能搬运机…...

UI自动化测试工具对企业具有重要意义

随着软件行业的不断发展&#xff0c;企业对高质量、高效率的软件交付有着越来越高的要求。在这个背景下&#xff0c;UI自动化测试工具成为了企业不可或缺的一部分。以下是UI自动化测试工具对企业的重要作用&#xff1a; 1. 提高软件质量 UI自动化测试工具能够模拟用户的操作&am…...

Linux--进程状态与优先级

概念 进程指的是程序在执行过程中的活动。进程是操作系统进行资源分配和调度的基本单位。 进程可以看作是程序的一次执行实体&#xff0c;它包含了程序代码、数据以及相关的执行上下文信息。操作系统通过创建、调度和管理多个进程来实现对计算机系统资源的有效利用。 每个进程…...

如何实现无公网ip固定TCP端口地址远程连接Oracle数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…...

Orchestrator源码解读2-故障失败发现

目录 前言 核心流程函数调用路径 GetReplicationAnalysis 故障类型和对应的处理函数 ​编辑 拓扑结构警告类型 核心流程总结 与MHA相比 前言 Orchestrator另外一个重要的功能是监控集群&#xff0c;发现故障。根据从复制拓扑本身获得的信息&#xff0c;它可以识别各种故…...

REST2SQL是什么?它有什么功能和特性?它值不值得我们去学习?我们该如何去学习呢?

REST2SQL是一种将RESTful API转换为SQL查询的工具或技术。它可以将RESTful API中的请求转换为对数据库的SQL查询&#xff0c;以便从数据库中检索、更新或删除数据。 REST2SQL的工作原理是通过分析RESTful API的请求参数和路径&#xff0c;将其转换为相应的SQL查询语句。这样可…...

Android 实现获取集合中出现重复数据的值和数量

方法一&#xff1a;使用HashMap和HashSet 创建一个HashMap&#xff0c;用于存储集合中的元素及其出现次数。 Map<String, Integer> map new HashMap<>();遍历集合&#xff0c;将每个元素作为键&#xff0c;将其出现次数作为值添加到HashMap中。 for (String it…...

【QT学习十一】QThread

一、引言 在现代软件开发中&#xff0c;多线程编程变得越来越重要&#xff0c;尤其是对于需要处理并发任务的应用程序。Qt C 框架提供了强大的多线程支持&#xff0c;使得开发者能够轻松地创建和管理多线程应用。 在 Qt 中&#xff0c;多线程的实现主要基于 QThread 类。QThrea…...

Mybatis 39_使用MBG生成代码

此2个插件均未晚装成功!!!! 安装 MyBatipse插件 MyBatipse插件 - 开发MyBatis应用的Eclipse插件- 自动完成- 有效性验证- Mapper视图使用MBG MyBatis Generator (MBG):根据底层数据表来自动生成Mapper组件只要两步即可: (1) 提供一个简单的配置文件,告诉MBG连接数据…...

Hudi metadata table(元数据表)

什么是metadata表 Metadata表即Hudi元数据表,是一种特殊的Hudi表,对用户隐藏。该表用于存放普通Hudi表的元数据信息。Metadata表包含在普通Hudi表内部,与Hudi表是一一对应关系。 元数据表的作用 ApacheHudi元数据表可以显著提高查询的读/写性能。元数据表的主要目的是消…...

提高iOS App开发效率的方法

引言 随着智能手机的普及&#xff0c;iOS App开发成为越来越受欢迎的技术领域之一。许多人选择开发iOS应用程序来满足市场需求&#xff0c;但是iOS App开发需要掌握一些关键技术和工具&#xff0c;以提高开发效率和质量。本文将介绍一些关键点&#xff0c;可以帮助你进行高效的…...

MPU机制与实现详解

目录 MPU机制与实现详解 Partition元素-MPU Partition实现元素OSApplication Partition元素-RTE MPU机制与实现详解 1、freedom from interference 此概念来自ISO26262-1&#xff1a;多个元素之间没有可能导致违反安全目标的级联故障&#xff0c;称之为免于干涉。 在左侧的…...

pom文件冲突引起的Excel无法下载

问题一&#xff1a;之前生产环境上可以进行下载Excel的功能突然不能用了 报错提示信息&#xff1a; NoClassDefFoundError: Could not initialize class org.apache.poi.xssf.usermodel.XSSFWorkbook&#xff0c; 在最开始初始化的时候找不到对应的类&#xff0c;虽然我的Libr…...

【HarmonyOS4.0】第十篇-ArkUI布局容器组件(二)

三、层叠布局容器&#xff08;Stack&#xff09; 堆叠容器组件 Stack的布局方式是把子组件按照设置的对齐方式顺序依次堆叠&#xff0c;后一个子组件覆盖在前一个子组件上边。 注意&#xff1a;Stack 组件层叠式布局&#xff0c;尺寸较小的布局会有被遮挡的风险&#xff0c; …...

PLECS如何下载第三方库并导入MOSFET 的xml文件,xml库路径添加方法及相关问题

1. 首先xml库的下载&#xff0c;PLECS提供了一个跳转的链接。 https://www.plexim.com/download/thermal_models 2. 下载一个库&#xff08;以最后一个Wolfspeed为例&#xff0c;属于CREE的SiC MOSFET&#xff09; 下载这个就行&#xff0c;都包含了。不信自己可以试试再下载…...

使用emu8086实现——子程序的设计

一、实验目的 学习子程序的结构、特点&#xff0c;以及子程序的设计和调试方法 二、实验内容 1、从字符串中删除一个字符&#xff0c;并存储到寄存器AX中。 代码及注释&#xff1a; data segmentstring db exas ;字符串内容leng dw $-string ; 字符串长度key db x …...

快速排序、归并排序、希尔排序(2023-12-25)

参考文章 十大经典排序算法总结整理_十大排序算法-CSDN博客 推荐文章 算法&#xff1a;归并排序和快排的区别_归并排序和快速排序的区别-CSDN博客 package com.tarena.test.B20; import java.util.Arrays; import java.util.StringJoiner; public class B25 { static i…...

Qt SDL2播放Wav音频

这里介绍两种方法来实现Qt播放Wav音频数据。 方法一&#xff1a;使用QAudioOutput pro文件中加入multimedia模块。 #include <QApplication> #include <QFile> #include <QAudioFormat> #include <QAudioOutput>int main(int argc, char *argv[]) {…...

[ACM学习] 动态规划基础之一二三维dp

课内学习的动态规划 有记忆的迭代 优化解的结构&#xff1a;原始问题的一部分解是子问题的解 三要素&#xff1a;1.子问题 2.状态的定义 3.状态转移方程 定义 线性dp的一道例题 dp[i]表示以位置 i 结尾的方案总数&#xff0c;dp[4]2&#xff0c;因为&#xff1a;首先只放一…...

Qt点击按钮在其附近弹出一个窗口

效果 FS_PopupWidget.h #ifndef FS_POPUPWIDGET_H #define FS_POPUPWIDGET_H#pragma once#include <QToolButton> #include <QWidgetAction> #include <QPointer>class QMenu;class FS_PopupWidget : public QToolButton {Q_OBJECTpublic:FS_PopupWidget(QW…...

Springboot注解@Configuration和@Bean注解作用,生命周期

简介&#xff1a; Configuration 类是定义 bean 配置的地方&#xff0c;而 Bean 方法是具体创建 bean 实例的方法。 Configuration 作用&#xff1a; Configuration 注解用于定义配置类&#xff0c;表明该类包含一个或多个 bean 定义的方法。Spring 容器在启动时会自动扫描这些…...

30天精通Nodejs--第十五天:Websocket

引言 这里我们将继续深入探讨另一项强大且实时性极高的网络通信技术——WebSocket。通过本篇文章,将全面了解如何在Node.js环境中利用WebSocket实现服务端与客户端之间双向、低延迟的数据传输,并掌握其基础用法以及一些高级应用场景。 基础用法 安装WebSocket库 在Node.j…...

C++深入学习之STL:2、适配器、迭代器与算法部分

适配器概述 C标准模板库(STL)中提供了几种适配器&#xff0c;这些适配器主要用于修改或扩展容器类的功能。STL中的适配器主要包括以下几种&#xff1a; 1、迭代器适配器&#xff1a;迭代器适配器提供了一种机制&#xff0c;可以将非迭代器对象转换为迭代器对象。比如back_ins…...

Tiktok/抖音旋转验证码识别

一、引言 在数字世界的飞速发展中&#xff0c;安全防护成为了一个不容忽视的课题。Tiktok/抖音&#xff0c;作为全球最大的短视频平台之一&#xff0c;每天都有数以亿计的用户活跃在其平台上。为了保护用户的账号安全&#xff0c;Tiktok/抖音引入了一种名为“旋转验证码”的安…...

【Java 设计模式】设计原则

文章目录 ✨单一职责原则&#xff08;SRP&#xff09;✨开放/封闭原则&#xff08;OCP&#xff09;✨里氏替换原则&#xff08;LSP&#xff09;✨依赖倒置原则&#xff08;DIP&#xff09;✨接口隔离原则&#xff08;ISP&#xff09;✨合成/聚合复用原则&#xff08;CARP&#…...

Druid连接池工具公式化SQL附踩坑记录

1. 需求 使用Druid连接池工具格式化sql用于回显时候美观展示 2. 代码示例 2.1 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version> </dependency> 2.2 ParseUtils…...

Linux内核--网络协议栈(二)UDP数据包发送

目录 一、引言 二、数据包发送 ------>2.1、数据发送流程 三、协议层注册 ------>3.1、socket系统调用 ------>3.2、socket创建 ------>3.3、协议族初始化 ------>3.4、对应协议的socket创建 ------>3.5、协议注册 四、通过套接字发送网络数据 --…...