热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

来自<stdatomic.h>的atomic_store/load是否适用于英特尔上未对齐的跨缓存行数据?

如何解决《来自<stdatomic.h>的atomic_store/load是否适用于英特尔上未对齐的跨缓存行数据?》经验,为你挑选了1个好方法。

使用atomic_store存储的数据和使用atomic_load加载的数据是否总是一致?

具体来说:C11程序访问故意放置在现代Intel CPU上高速缓存行之间边界的64位数据.它使用atomic_store和atomic_load(from )从多个线程(在不同的核心上运行)访问此数据.

数据是否总是显得一致,或者加载它(atomic_load)有时会有一些属于旧值的字节,以及属于更新值的其他字节?

以下是基本的结构和变量定义以及程序的有趣部分,它们在一个循环中,并行地从多个线程发生:

struct Data {
    uint8_t bytes[CACHELINE__BYTECOUNT - 4];
    atomic_uint_fast64_t u64;
} __attribute__((packed)) __attribute__((aligned ((CACHELINE__BYTECOUNT))));

#define VAL1 (0x1111111111111111)
#define VAL2 (0xFFFFFFFFFFFFFFFF)

static struct Data data = { .u64 = VAL1 };

...

    for (uint32_t j = 0; j <1000; j++) {
        atomic_store(&data.u64, VAL1);
        atomic_store(&data.u64, VAL2);
    }
    const uint64_t val = atomic_load(&data.u64);
    /* is 'val' always VAL1 or VAL2? */

(完全可运行的程序:https://gist.github.com/sinelaw/1230d4675d6a4fff394110f17e463954)

用gcc 6.3.0和clang 3.7检查它显示它不是原子的:

$ clang -std=c11 -Wall -Wextra /tmp/atomic.c -o /tmp/atomic -lpthread
$ /tmp/atomic
ERROR: oh no, got: 11111111FFFFFFFF

所以无论是程序中存在错误,还是我误解了,或者编译器中存在错误.



1> Art..:

正确编写的程序无法获取未正确对齐的对象.正确对齐的int64无法跨越缓存行.

所以你的问题的答案是:你的程序中有一个错误.您通过使用非标准构造(__attribute__)来破坏事物而故意引入的错误.

对于编译器来说,确保stdatomic适用于未对齐的值是很疯狂的,因为这需要一个全局锁,这是stdatomic特别要避免的.


@sinelaw这可能是使用`packed`的最糟糕的理由.在某些边缘情况下,`packed`很有用,但这不是其中之一.对此的警告将是完全多余的,因为每次使用`packed`时都应该发出警告,因为这是"打包"唯一的事情 - 它会打破对齐.唯一不会发出的是"打包"没有效果."填充"不是编译器用来搞定你的东西,它是在数据正确对齐后留下的东西(这就是为什么我不喜欢单词"padding").
推荐阅读
  • pypy 真的能让 Python 比 C 还快么?
    作者:肖恩顿来源:游戏不存在最近“pypy为什么能让python比c还快”刷屏了,原文讲的内容偏理论,干货比较少。我们可以再深入一点点,了解pypy的真相。正式开始之前,多唠叨两句 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • 本文详细介绍了 Node.js 中 OS 模块的 arch 方法,包括其功能、语法、参数以及返回值,并提供了具体的使用示例。 ... [详细]
  • C语言是计算机科学和编程领域的基石,许多初学者在学习过程中会感到困惑。本文将详细介绍C语言的基本概念、关键语法和实用示例,帮助你快速上手C语言。 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • C基本语法C程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。对象-对象具有状态和行为 ... [详细]
  • 深入解析mt_allocator内存分配器(二):多线程与单线程场景下的实现
    本文详细介绍了mt_allocator内存分配器在多线程和单线程环境下的实现机制。该分配器以2的幂次方字节为单位分配内存,支持灵活的配置和高效的性能。文章分为内存池特性描述、内存池实现、单线程内存池实现、内存池策略类实现及多线程内存池实现等部分,深入探讨了内存池的初始化、内存分配与回收的具体实现。 ... [详细]
  • 深入解析C++ Atomic编程中的内存顺序
    在多线程环境中,为了防止多个线程同时修改同一数据导致的竞争条件,通常会使用内核级同步对象,如事件、互斥锁和信号量等。然而,这些方法往往伴随着高昂的上下文切换成本。本文将探讨如何利用C++11中的原子操作和内存顺序来优化多线程编程,减少不必要的开销。 ... [详细]
  • SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
    自从何凯明提出导向滤波后,因为其算法的简单性和有效性,该算法得到了广泛的应用,以至于新版的matlab都将其作为标准自带的函数之一了&#x ... [详细]
  • 本文详细介绍了如何在 Ubuntu 14.04 系统上搭建仅使用 CPU 的 Caffe 深度学习框架,包括环境准备、依赖安装及编译过程。 ... [详细]
  • 本文介绍了一种方法,通过使用Python的ctypes库来调用C++代码。具体实例为实现一个简单的加法器,并详细说明了从编写C++代码到编译及最终在Python中调用的全过程。 ... [详细]
  • 探讨如何在C++中,当子类实例存储在父类类型的向量中时,正确访问子类特有的成员变量或方法。 ... [详细]
  • 本文深入探讨了Linux内核中进程地址空间的设计与实现,包括虚拟地址空间的概念、内存描述符`mm_struct`的作用、内核线程与用户进程的区别、进程地址空间的分配方法、虚拟内存区域(VMA)的结构以及地址空间与页表之间的映射机制。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 如何解决《在英特尔SGX中禁用系统调用意味着什么》经验,为你挑选了1个好方法。 ... [详细]
author-avatar
mobiledu2502876193
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有