- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
float myfloats[2];
// thread A:
myFloats[0] = 1.0;
// thread B:
myFloats[1] = 1.0;
假设线程 A 将始终访问索引 0,线程 B 始终访问索引 1。这是否安全或数组是否会损坏?
最佳答案
C11 n1570 草案标准似乎断言这是安全的,但我断言这是不明智的。
我的论点基于数组的元素不能在内存中重叠这一事实,以及 C11 标准草案的以下条款。
5.1.2.4 Multi-threaded executions and data races
4. Two expression evaluations conflict if one of them modifies a memory location and the other one reads or modifies the same memory location.
25. The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior.
27. NOTE 13 Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race. This includes implementations of data member assignment that overwrite adjacent members in separate memory locations. We also generally preclude reordering of atomic loads in cases in which the atomics in question may alias, since this may violate the "visible sequence" rules.
28. NOTE 14 Transformations that introduce a speculative read of a potentially shared memory location may not preserve the semantics of the program as defined in this standard, since they potentially introduce a data race. However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races. They would be invalid for a hypothetical machine that is not tolerant of races or provides hardware race detection.
我们在这里了解到,两个线程在同一内存位置上执行冲突操作是 UB,但是编译器“通常被排除在外”将抽象机器不会执行的“潜在共享”内存位置的分配引入.
您断言您的线程只能访问(读取和写入)它们自己特定索引处的元素。毫无疑问,他们不会访问相同的内存位置,因此在我看来,只要您满足所有其他约束条件,例如 float
的正确对齐,您所做的就是安全的变量。
但是,我质疑按照您的建议行事的智慧。由于这两个内存位置是连续的,您可能会遇到严重的错误共享 问题。这是因为 CPU 通常以大约 32 或 64 个连续字节的“行”缓存内存,并使用 MESI 协议(protocol)传达缓存状态。
如果在一个核心上运行的线程在此缓存行中任何地方执行写入操作,则在其他 核心中找到的缓存行的所有副本以及其中包含的所有内容都是无效,通常会导致其他内核上的线程需要从主内存中重新读取更新后的副本。这比从缓存访问慢几倍。
真正的共享如果相关线程都访问缓存行的同一部分,因为这种无效被证明是为了防止通信线程使用陈旧数据。
另一方面,如果线程都访问同一缓存行的不同部分,则会发生虚假共享。在这种情况下,无效是不必要的,但由于访问彼此接近,硬件还是执行了无效,对所有访问进行了惩罚。
关于c - 从两个不同索引处的 2 个不同线程写入 float 组是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20458673/
我有这个代码 var myChart = new FusionCharts("../themes/clean/charts/hbullet.swf", "myChartId", "400", "75
既然写入是立即进行的(复制到内核缓冲区并返回),那么使用 io_submit 进行写入有什么好处? 事实上,它 (aio/io_submit) 看起来更糟,因为您必须在堆上分配写入缓冲区并且不能使用基
我正在使用 mootool 的 Request.JSON 从 Twitter 检索推文。收到它后,我将写入目标 div 的 .innerHTML 属性。当我在本地将其作为文件进行测试时,即 file:
最终,我想将 Vertica DB 中的数据抓取到 Spark 中,训练机器学习模型,进行预测,并将这些预测存储到另一个 Vertica DB 中。 当前的问题是确定流程最后部分的瓶颈:将 Spark
我使用 WEKA 库编写了一个 Java 程序, 训练分类算法 使用经过训练的算法对未标记的数据集运行预测 将结果写入 .csv 文件 问题在于它当前写出离散分类结果(即算法猜测一行属于哪个类别)。我
背景 - 我正在考虑使用 clickonce 通过 clickonce(通过网站)部署 WinForms 应用程序。相对简单的应用程序的要素是: - 它是一个可执行文件和一个数据库文件(sqlite)
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
我正在读取 JSON 文件,取出值并进行一些更改。 基本上我向数组添加了一些值。之后我想将其写回到文件中。当我将 JSONArray 写回文件时,会被写入字符串而不是 JSONArray 对象。怎样才
我为两个应用程序使用嵌入式数据库,其中一个是服务器,另一个是客户端。客户端应用程序。可以向服务器端发送获取数据请求以检索数据并显示在表格(或其他)中。问题是这样的:如何将获取的数据保存(写入)到页面文
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
从问题得出问题:找到所有 result = new ArrayList(); for (int i = 2; i >(i%8) & 0x1) == 0) { result.add(i
由于某种原因,它没有写入 CSV。谁能明白为什么它不写吗? def main(): list_of_emails = read_email_csv() #read input file, cr
关闭。 这个问题是 not reproducible or was caused by typos 。它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能在这里出现,
我目前正在开发一个保存和加载程序,但我无法获得正确的结果。 编写程序: #include #include #define FILENAME "Save" #define COUNT 6 type
import java.io.*; public class Main2 { public static void main(String[] args) throws Exception {
我需要使用预定义位置字符串“Office”从所有日历中检索所有 iOS 事件,然后将结果写入 NSLog 和 UITextView。 到目前为止,这是我的代码: #import "ViewCo
我正在尝试将 BOOL 值写入 PFInstallation 中的列,但会不停地崩溃: - (IBAction)pushSwitch:(id)sender { NSUserDefaults *push
我以前在学校学过一些简单的数据库编程,但现在我正在尝试学习最佳实践,因为我正在编写更复杂的应用程序。写入 MySQL 数据库并不难,但我想知道让分布式应用程序写入 Amazon EC2 上的远程数据库
是否可以写回到ResourceBundle?目前我正在使用 ResourceBundle 来存储信息,在运行时使用以下内容读取信息 while(ResourceBundle.getBundle("bu
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我是一名优秀的程序员,十分优秀!