在C++ 11标准,部分1.10/5提到,但不正式定义的术语acquire operation,release operation和consume operation.然后在第29节继续使用这些术语来描述某些内存排序,原子操作和内存栅栏的操作.例如,关于"顺序和一致性"的29.3/1表示:
memory_order_release,memory_order_acq_rel和memory_order_seq_cst:存储操作在受影响的内存位置上执行释放操作 [强调添加].
这种类型的语言在第29节中重复出现,但令我烦恼的是,memory_order枚举的所有含义都基于操作类型,这些类型本身似乎没有被标准正式化,但必须对它们有一些共同的意义.作为定义有效.
换句话说,如果我说"一个酒吧是一个翻转的foo",bar和foo的具体含义是模棱两可的,因为这两个术语都没有正式定义.只定义了它们的相对性质.
请问C++的11个标准,或其他一些C++ 11标准委员会文件正式准确定义的是什么acquire operation,release operation等等是,或者是这些简单的通常理解的术语?如果是后者,是否有一个很好的参考被认为是这些操作含义的行业标准?我特别要求,因为硬件内存一致性模型不是相同的,因此我认为必须有一些共同商定的引用,允许那些实现编译器等的人正确地将这些操作的语义转换为本机程序集命令.
Consider this simple C++ function to calculate the prefix sum of an array:
void prefix_sum(const uint32_t* input, uint32_t* output, size_t size) {
uint32_t total = 0;
for (size_t i = 0; i < size; i++) {
total += input[i];
output[i] = total;
}
}
Run Code Online (Sandbox Code Playgroud)
The loop compiles to the following assembly on gcc 5.5:
.L5:
add ecx, DWORD PTR [rdi+rax*4]
mov DWORD PTR [rsi+rax*4], ecx
add rax, 1
cmp rdx, rax
jne .L5
Run Code Online (Sandbox Code Playgroud)
I don't see anything that would prevent …
我想知道各种大小的循环如何在最近的x86处理器上执行,作为uop数的函数.
以下是彼得·科德斯(Peter Cordes)的一句话,他在另一个问题中提出了非多数的问题:
我还发现,如果循环不是4 uop的倍数,则循环缓冲区中的uop带宽不是每个循环的常数4.(即它是abc,abc,......;不是abca,bcab,......).遗憾的是,Agner Fog的microarch doc对循环缓冲区的这种限制并不清楚.
问题是关于循环是否需要是N uop的倍数才能以最大uop吞吐量执行,其中N是处理器的宽度.(即最近的英特尔处理器为4).在谈论"宽度"和计算微动时,有很多复杂因素,但我大多想忽略这些因素.特别是,假设没有微观或宏观融合.
Peter给出了以下一个循环,其中包含7个uop的循环:
一个7-uop循环将发出4 | 3 | 4 | 3 | ...的组我没有测试更大的循环(不适合循环缓冲区),看看是否有可能从下一个指令开始迭代发布在与其分支相同的组中,但我不假设.
更一般地说,声称是x在其体内具有uops 的循环的每次迭代将至少进行ceil(x / 4)迭代,而不是简单地迭代x / 4.
对于部分或全部最新的x86兼容处理器,这是真的吗?
performance x86 assembly cpu-architecture micro-optimization
想象一下,您希望将一系列x86汇编指令与某些边界对齐.例如,您可能希望将循环对齐到16或32字节的边界,或者将指令打包以使它们有效地放置在uop缓存中或其他任何位置.
实现这一目标的最简单方法是单字节NOP指令,紧接着是多字节NOP.虽然后者通常效率更高,但这两种方法都不是免费的:NOP使用前端执行资源,并且还计入现代x86上的4宽1重命名限制.
另一个选择是以某种方式延长一些指令以获得所需的对齐.如果这样做没有引入新的停顿,它似乎比NOP方法更好.如何在最近的x86 CPU上有效地延长指令?
在理想的世界中,延长技术同时是:
有一种方法不可能同时满足所有上述要点,因此很好的答案可能会解决各种权衡问题.
1 AMD Ryzen的限制为5或6.
我想实现一个适当的write(2)循环,它接受一个缓冲区并一直调用,write直到写入整个缓冲区.
我想基本的方法是这样的:
/** write len bytes of buf to fd, returns 0 on success */
int write_fully(int fd, char *buf, size_t len) {
while (len > 0) {
ssize_t written = write(fd, buf, len);
if (written < 0) {
// some kind of error, probably should try again if its EINTR?
return written;
}
buf += written;
len -= written;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
...但是这引发了一个问题:是否write()可以有效地返回写入的0字节以及在这种情况下该怎么做.如果情况仍然存在,上面的代码只会热情地转动,write这似乎是一个坏主意.只要返回零以外的其他内容,您就可以取得进展.
手册页write有点含糊不清.它说,例如:
成功时,返回写入的字节数(零表示没有写入).
这似乎表明在某些情况下这是可能的.只显示了一个这样的场景: …
是否通过Axis2线程安全从WSDL生成客户端存根?
当然,"线程安全"不是一个严格定义的术语,所以我至少对以下内容感兴趣:
是不同的不同的线程同时访问相同的stub类的实例,用同样有效的行为作为单线程运行?
同一个存根类的单个实例是否可以由不同的线程并发访问,并且在单线程执行中以相同的方式交错相同的有效行为?
给定一个无向图,我想生成所有子图,这些子图是大小为N的树,其中size指的是树中边的数量.
我知道它们中有很多(至少对于具有恒定连通性的图形呈指数多) - 但这很好,因为我相信节点和边缘的数量使得这对于至少小的N值(例如10或更小)来说易于处理).
该算法应该具有内存效率 - 也就是说,它不需要同时在内存中包含所有图形或其中的一些大部分子集,因为即使对于相对较小的图形,这也可能超过可用内存.所以像DFS这样的东西是可取的.
给出起始图graph和所需长度,这是我在伪代码中的想法N:
选择任意节点,root作为起点并调用alltrees(graph, N, root)
alltrees(graph, N, root)
given that node root has degree M, find all M-tuples with integer, non-negative values whose values sum to N (for example, for 3 children and N=2, you have (0,0,2), (0,2,0), (2,0,0), (0,1,1), (1,0,1), (1,1,0), I think)
for each tuple (X1, X2, ... XM) above
create a subgraph "current" initially empty
for each integer Xi in X1...XM (the …Run Code Online (Sandbox Code Playgroud) 单个进程中的两个不同线程可以通过读取和/或写入来共享公共存储器位置.
通常,这种(有意)共享是使用lockx86上的前缀使用原子操作实现的,该前缀对于lock前缀本身(即,无竞争成本)具有相当广为人知的成本,并且当实际共享高速缓存行时还具有额外的一致性成本(真或假共享).
在这里,我对生产 - 消费者成本感兴趣,其中单个线程P写入内存位置,另一个线程`C从内存位置读取,都使用普通读取和写入.
在同一个套接字上的不同内核上执行此类操作的延迟和吞吐量是多少,并且在最近的x86内核上在同一物理内核上执行兄弟超线程时进行比较.
在标题中,我使用术语"超级兄弟"来指代在同一核心的两个逻辑线程上运行的两个线程,以及核心间兄弟,以指代在不同物理核心上运行的两个线程的更常见情况.
我正在寻找Supplier<T>番石榴的反面.我希望它会被称为Consumer- 不 - 或Sink- 存在,但它是为了原始价值.
它隐藏在某处,我想念它吗?
我希望看到它有同样的原因Supplier.诚然,使用不太常见,但是Suppliers,例如,许多静态方法将以类似的方式应用,并且在一行中表达诸如"在此可迭代中发送该供应商的每个值"之类的事情将是有用的.
在此期间,Predicate和Function<T,Void>丑陋的解决方法.
我最近看到多个声明,谈论Java(以及基于JVM的语言,如Scala)在性能上与C/C++代码的可比性.
例如,从ScalaLab项目的描述:
基于Scala的脚本编写速度,接近本机和优化Java代码的速度,因此与基于C/C++的科学代码接近甚至更好!
有人能指出我对这些JVM优化的概述吗?是否有任何真正的基准支持这一主张或提供一些真实的比较?
performance ×4
x86 ×4
java ×3
assembly ×2
c++ ×2
optimization ×2
algorithm ×1
axis2 ×1
c ×1
c++11 ×1
concurrency ×1
file-io ×1
graph ×1
graph-theory ×1
guava ×1
intel ×1
jvm ×1
linux ×1
native-code ×1
posix ×1
scala ×1
standards ×1
tree ×1
web-services ×1