小编HCS*_*CSF的帖子

非 const 何时按值捕获引用?

我正在查看 n4713 C++ 标准中的 8.4.4.1:

void f() {
float x, &r = x;
[=] {
   decltype(x) y1; // y1 has type float
   decltype((x)) y2 = y1; // y2 has type float const& because this lambda is not mutable and x is an lvalue
   decltype(r) r1 = y1; // r1 has type float&
   decltype((r)) r2 = y2; // r2 has type float const&
};
}
Run Code Online (Sandbox Code Playgroud)

标准说 r2 有 type float const&,然后我尝试打印出类型:

#include <iostream>

template <class T>
void print_type() {
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ g++ c++17

20
推荐指数
1
解决办法
247
查看次数

SIMD指令降低CPU频率

我读了这篇文章。它谈到了为什么AVX-512指令:

英特尔最新的处理器具有高级指令(AVX-512),这可能会导致内核或其他CPU的运行速度变慢,这是因为它们使用了多少电量。

我认为在Agner的博客上也提到了类似的内容(但我找不到确切的帖子)。

我想知道Skylake支持的其他哪些指令会产生类似的效果,即它们会降低功耗以在以后最大化吞吐量吗?所有前缀v指令(如vmovapdvmulpdvaddpdvsubpdvfmadd213pd)?

我正在尝试编译说明列表,以避免在为Xeon Skylake编译C ++应用程序时避免。

optimization x86 intel compiler-optimization avx512

12
推荐指数
2
解决办法
564
查看次数

模板函数匹配特化

我在 GCC 10.0 和 Clang 10.0 中尝试了以下代码:

template <template <typename> typename>
struct Foo {
    Foo() { std::cout << "generic" << std::endl; }
};

template <typename>
struct Bar {};

template <typename T>
using Fake_Bar = Bar<T>;

template <>
struct Foo<Bar> {
    Foo() { std::cout << "specialization" << std::endl; }
};

int main() {
    Foo<Bar> a;
    Foo<Fake_Bar> b;
}
Run Code Online (Sandbox Code Playgroud)

他们给出了不同的输出:

海湾合作委员会:

specialization
specialization
Run Code Online (Sandbox Code Playgroud)

铛:

specialization
generic
Run Code Online (Sandbox Code Playgroud)

根据 C++17 标准,哪一个是正确的?规则是什么?

c++ language-lawyer c++17

11
推荐指数
0
解决办法
72
查看次数

在特定NUMA节点上创建命名共享内存?

与此类似帖子,我想创建一个名为共享内存段(通过创建shm_open()+ mmap()特定的NUMA节点(不一定是本地)上的CentOS 7).该帖子建议通过使用来实现numa_move_pages().

我还有几个问题:

  1. 如果另一个进程(在不同NUMA的本地核心上运行)稍后启动并且mmap()s到同一个命名的共享内存段,OS是否会决定将命名的共享内存段移动到此进程的本地NUMA?如果是,我该如何预防呢?

  2. 是否还有其他情况,在我指定后,命名共享内存段将被移动到另一个NUMA numa_move_pages()

  3. 给定一个命名的共享内存段/shm/dev,如何检查它属于哪个NUMA节点?

我查看了numactl,它的--membind选项是我想要的,但我不确定如果两个不同的进程使用--membind2个不同的节点会产生什么影响.谁赢?如果#3得到解答,我想我可以测试一下.

谢谢!

c linux shared-memory numactl

9
推荐指数
1
解决办法
328
查看次数

推导返回类型

#include <iostream>
#include <vector>

template<typename Container, typename Index>
decltype(auto)
foo(Container&& c, Index i) {
    return std::forward<Container>(c)[i];
}

template<typename Container, typename Index>
decltype(auto)
bar(Container&& c, Index i) {
    return c[i];
}

int main() {
    std::vector<uint32_t> q{1, 3, 5};
    std::vector<uint32_t> r{2, 4, 6};

    std::cout << "lvalue" << std::endl;
    std::cout << foo(q, 1) << std::endl;
    std::cout << bar(q, 1) << std::endl;

    std::cout << "rvalue" << std::endl;
    std::cout << foo(std::move(q), 1) << std::endl;
    std::cout << bar(std::move(r), 1) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

foo()和的返回类型有什么区别bar()? …

c++ c++14

7
推荐指数
1
解决办法
90
查看次数

std::atomic::is_always_lock_free = true 的真正含义是什么?

我有以下代码:

#include <atomic>

int main () {
    std::atomic<uint32_t> value(0);
    value.fetch_add(1, std::memory_order::relaxed);
    static_assert(std::atomic<uint32_t>::is_always_lock_free);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它可以编译,所以这意味着std::atomic<uint32_t>::is_always_lock_free是真的。

然后,使用 gcc 10 和 的汇编代码如下所示-std=c++20 -O3 -mtune=skylake-avx512 -march=skylake-avx512

0000000000401050 <main>:
  401050:       c7 44 24 fc 00 00 00    mov    DWORD PTR [rsp-0x4],0x0
  401057:       00 
  401058:       f0 ff 44 24 fc          lock inc DWORD PTR [rsp-0x4]
  40105d:       31 c0                   xor    eax,eax
  40105f:       c3                      ret    
Run Code Online (Sandbox Code Playgroud)

许多帖子指出,读-修改-写操作(fetch_add()此处)不能是没有锁的原子操作。

我的问题是std::atomic::is_always_lock_free存在的true真正含义是什么。

该页面说明Equals true if this atomic type is …

c++ lock-free c++11 stdatomic

7
推荐指数
1
解决办法
921
查看次数

GCC 在 Boost Source 中的警告

我正在使用 boost 1.63,当我编译包含#include <boost/algorithm/string.hpp>.

海湾合作委员会抱怨:

In file included from /opt/boost/boost/mpl/aux_/na_assert.hpp:23,
                 from /opt/boost/boost/mpl/arg.hpp:25,
                 from /opt/boost/boost/mpl/placeholders.hpp:24,
                 from /opt/boost/boost/iterator/iterator_categories.hpp:17,
                 from /opt/boost/boost/iterator/iterator_facade.hpp:14,
                 from /opt/boost/boost/range/iterator_range_core.hpp:27,
                 from /opt/boost/boost/range/iterator_range.hpp:13,
                 from /opt/boost/boost/range/as_literal.hpp:22,
                 from /opt/boost/boost/algorithm/string/trim.hpp:19,
                 from /opt/boost/boost/algorithm/string.hpp:19,
         from [my source that includes <boost/algorithm/string.hpp>]
/opt/boost/boost/mpl/assert.hpp:188:21: warning: unnecessary parentheses in declaration of ‘assert_arg’ [-Wparentheses]
 failed ************ (Pred::************
                     ^
/opt/boost/boost/mpl/assert.hpp:193:21: warning: unnecessary parentheses in declaration of ‘assert_not_arg’ [-Wparentheses]
 failed ************ (boost::mpl::not_<Pred>::************
                     ^
Run Code Online (Sandbox Code Playgroud)

我查看了来源,抱怨部分是:

template< typename Pred >
failed ************ (Pred::************
      assert_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type )
    );

template< typename Pred …
Run Code Online (Sandbox Code Playgroud)

c++ boost

6
推荐指数
1
解决办法
2801
查看次数

在同一地址上具有 2 个 std::atomic 变量的两个不同进程?

我阅读了 C++ 标准 (n4713) 的 § 32.6.1 3:

无锁的操作也应该是无地址的。也就是说,通过两个不同地址对同一内存位置的原子操作将进行原子通信。实现不应依赖于任何每个进程的状态。此限制允许通过多次映射到进程的内存和在两个进程之间共享的内存进行通信。

所以听起来可以在同一内存位置执行无锁原子操作。我想知道怎么做。

假设我在 Linux 上有一个命名的共享内存段(通过 shm_open() 和 mmap())。例如,如何对共享内存段的前 4 个字节执行无锁操作?

起初,我以为我可以只reinterpret_cast指向std::atomic<int32_t>*. 但后来我读到了这个。它首先指出 std::atomic 可能没有相同大小的 T 或对齐:

当我们设计 C++11 原子时,我误以为可以使用诸如

int x; reinterpret_cast<atomic<int>&>(x).fetch_add(1);
Run Code Online (Sandbox Code Playgroud)

如果 atomic 和 int 的表示不同,或者它们的对齐方式不同,这显然会失败。但我知道这在我关心的平台上不是问题。而且,在实践中,我可以通过在编译时检查大小和对齐方式匹配来轻松测试问题。

Tho,在这种情况下对我来说很好,因为我在同一台机器上使用共享内存,并且在两个不同的进程中投射指针将“获取”相同的位置。但是,文章指出编译器可能不会将强制转换的指针视为指向原子类型的指针:

然而,这不能保证是可靠的,即使在人们可能期望它工作的平台上,因为它可能会混淆编译器中基于类型的别名分析。编译器可能会假设 int 也不会作为atomic<int>. (见 3.10,[Basic.lval],最后一段。)

欢迎任何输入!

c++ shared-memory c++11 stdatomic

3
推荐指数
1
解决办法
871
查看次数

在C ++标准中滥用std :: memory_order :: relax的示例[n4713中的algorithms.parallel.exec / 5]

std::memory_order::relaxed在C ++ Standard 中滥用的示例之一:

std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
    x.fetch_add(1, std::memory_order::relaxed);
    // spin wait for another iteration to change the value of x
    while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order
});
Run Code Online (Sandbox Code Playgroud)

然后说,

上面的示例取决于迭代的执行顺序,并且如果两个迭代均在同一执行线程上顺序执行,则不会终止。

问题:

  1. 注释说:“不正确:假定执行顺序”。什么是“假定执行顺序”?我想念它。

  2. “以上示例取决于迭代的执行顺序”中的“迭代”指的是什么?这是否意味着while循环中的迭代?还是指迭代std::for_each

  3. 如果的迭代std::for_each由不同的线程并行执行,那么迭代/线程之一不会退出仍然不是真的吗?因为x.fetch_add(1, std::memory_order::relaxed)是原子的,所以一个线程将生成x1,另一个线程将生成x2,并且两个线程的x == 1都是不可能的。没有?

c++ c++11 relaxed-atomics c++17

3
推荐指数
1
解决办法
79
查看次数

C++中的算术溢出17

  1. 在算术溢流井每C++ 17定义uint8_t,uint16_t,uint32_t,uint64_t?如果是,那么定义的行为是什么(来自C++标准的摘录非常感谢)
  2. 在算术溢流井每C++ 17定义int8_t,int16_t,int32_t,int64_t?(摘自C++标准非常感谢)
  3. 如果上面的任何一个或全部是特定于实现的,那么g ++和clang的定义是什么?
  4. 如果它是特定于体系结构的(正如Havenard指出的那样),我的问题特定于x86(-64).
  5. 如果我做一个较小的unsigned int - 更大的unsigned int,它定义得很好怎么办?

我看到这篇文章的第一个答案提到我的问题#1,它是用C标准定义的,虽然他没有引用它,我在C++标准中找不到任何东西.

=================

更新1:

因为它是错误的术语而删除了每次"下溢"(感谢@ach).添加了#5来表达我对"下溢"的真正含义(错误)

c++ x86 g++ clang language-lawyer

2
推荐指数
1
解决办法
279
查看次数