小编Zul*_*lan的帖子

为什么std :: fill(0)比std :: fill(1)慢?

我在一个系统std::fill上观察到,与常量值或动态值相比,std::vector<int>设置常量值时,大型系统显着且持续地较慢:01

5.8 GiB/s vs 7.5 GiB/s

但是,对于较小的数据大小,结果是不同的,其中fill(0)更快:

不同数据大小的单线程性能

对于4个GiB数据大小的多个线程,fill(1)显示更高的斜率,但达到的峰值远低于fill(0)(51 GiB/s对90 GiB/s):

大数据大小的各种线程计数的性能

这提出了次要问题,为什么峰值带宽fill(1)要低得多.

测试系统是一个双插槽Intel Xeon CPU E5-2680 v3,设置为2.5 GHz(通道/sys/cpufreq),带有8x16 GiB DDR4-2133.我使用GCC 6.1.0(-O3)和英特尔编译器17.0.1(-fast)进行了测试,结果都相同.GOMP_CPU_AFFINITY=0,12,1,13,2,14,3,15,4,16,5,17,6,18,7,19,8,20,9,21,10,22,11,23被设定了.Strem/add/24个线程在系统上获得85 GiB/s.

我能够在不同的Haswell双插槽服务器系统上重现这种效果,但没有任何其他架构.例如在Sandy Bridge EP上,内存性能是相同的,而在缓存fill(0)中则要快得多.

这是重现的代码:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <omp.h>
#include <vector>

using value = int;
using vector = std::vector<value>;

constexpr size_t write_size = 8ll * 1024 * 1024 * 1024;
constexpr size_t …
Run Code Online (Sandbox Code Playgroud)

c++ performance x86 memset compiler-optimization

65
推荐指数
2
解决办法
2366
查看次数

数组语法与指针语法和代码生成?

Richard Reese所着的"理解和使用C指针"一书中,它在第85页说

int vector[5] = {1, 2, 3, 4, 5};
Run Code Online (Sandbox Code Playgroud)

生成的代码与生成的代码vector[i]不同*(vector+i).该表示法vector[i]生成从位置向量开始的机器代码,从该位置移动 i位置,并使用其内容.符号*(vector+i)生成的机器代码从位置开始vector,添加 i到地址,然后使用该地址的内容.结果相同,生成的机器代码不同.这种差异对大多数程序员来说很少有意义.

你可以在这里看到摘录.这段经文是什么意思?在什么情况下,任何编译器都会为这两个编译器生成不同的 "移动"与基础之间是否存在差异,而"添加"基数是否存在差异?我无法让它在GCC上工作 - 生成不同的机器代码.

c arrays pointers pointer-arithmetic errata

54
推荐指数
5
解决办法
3306
查看次数

调整std :: vector <std :: unique_ptr <T >>的大小

一般概念似乎与正确使用的拥有原始指针相比没有时间开销,只要std::unique_ptr足够的优化.

但是std::unique_ptr,特别是在复合数据结构中使用std::vector<std::unique_ptr<T>>呢?例如,调整矢量的基础数据的大小,这可能发生在push_back.各地要隔离性能,我环路pop_back,shrink_to_fit,emplace_back:

#include <chrono>
#include <vector>
#include <memory>
#include <iostream>

constexpr size_t size = 1000000;
constexpr size_t repeat = 1000;
using my_clock = std::chrono::high_resolution_clock;

template<class T>
auto test(std::vector<T>& v) {
    v.reserve(size);
    for (size_t i = 0; i < size; i++) {
        v.emplace_back(new int());
    }
    auto t0 = my_clock::now();
    for (int i = 0; i < repeat; i++) {
        auto back = std::move(v.back()); …
Run Code Online (Sandbox Code Playgroud)

c++ vector compiler-optimization unique-ptr c++11

33
推荐指数
2
解决办法
2290
查看次数

在bash中捕获SIGINT,处理并忽略

是否有可能在bash中拦截一个SIGINT,做一些事情,然后忽略它(保持bash运行).

我知道我可以忽略SIGINT

trap '' SIGINT
Run Code Online (Sandbox Code Playgroud)

我也可以用sigint做点什么

trap handler SIGINT
Run Code Online (Sandbox Code Playgroud)

但是在handler执行之后仍然会停止脚本.例如

#!/bin/bash

handler()
{
    kill -s SIGINT $PID
}

program &
PID=$!

trap handler SIGINT

wait $PID

#do some other cleanup with results from program
Run Code Online (Sandbox Code Playgroud)

当我按下ctrl + c时,将发送SIGINT to program,但bash将跳过waitBEFORE程序正确关闭并在其信号处理程序中创建其输出.

使用@suspectus答案我可以wait $PID改为:

while kill -0 $PID > /dev/null 2>&1
do
    wait $PID
done
Run Code Online (Sandbox Code Playgroud)

这实际上对我有用我只是不是100%确定这是'干净'还是'肮脏的解决方法'.

bash

28
推荐指数
2
解决办法
2万
查看次数

与std :: minmax和rvalues的结构化绑定

当使用std::minmax结构化绑定时,我遇到了一个相当微妙的错误.似乎传递的rvalues并不总是像人们期望的那样被复制.最初我T operator[]() const在自定义容器上使用a ,但它似乎与文字整数相同.

#include <algorithm>
#include <cstdio>
#include <tuple>

int main()
{
    auto [amin, amax] = std::minmax(3, 6);
    printf("%d,%d\n", amin, amax); // undefined,undefined

    int bmin, bmax;
    std::tie(bmin, bmax) = std::minmax(3, 6);
    printf("%d,%d\n", bmin, bmax); // 3,6
}
Run Code Online (Sandbox Code Playgroud)

使用GCC 8.1.1 -O1 -Wuninitialized将导致0,0打印为第一行,并且:

warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]
Run Code Online (Sandbox Code Playgroud)

Clang 6.0.1 at -O2也会在没有警告的情况下给出错误的第一个结果.

-O0GCC给出正确的结果而没有警告.对于clang,结果似乎是正确的-O1-O0.

在rvalue仍然有效被复制的意义上,第一行和第二行不应该是等价的吗?

另外,为什么这取决于优化级别?特别是我对GCC没有发出任何警告感到惊讶.

c++ rvalue c++17 structured-bindings

19
推荐指数
2
解决办法
725
查看次数

isend和issend有什么区别?

需要澄清我对发送类型中给出的isend和issend的理解

我的理解是,一旦发送缓冲区空闲,即所有数据都被释放后,isend将返回.另一方面,Issend仅在收到获取/未获取整个数据的确认时才返回.这就是全部吗?

mpi

15
推荐指数
1
解决办法
5538
查看次数

存在使用命名空间时的全局范围解析

请考虑以下代码:

namespace foo {
  namespace bar {
    class foo {};
  }
  class baz {};
}
using namespace foo::bar;

::foo::baz mybaz;
Run Code Online (Sandbox Code Playgroud)

这段代码有效吗?还是::foo含糊不清?或者::foo指的class foo是,没有::foo::baz.

谈到编译器,gcc 6.1.1似乎认为后者:

scope.cpp:9:8: error: ‘baz’ in ‘class foo::bar::foo’ does not name a type
 ::foo::baz mybaz;
        ^~~
Run Code Online (Sandbox Code Playgroud)

另一方面gcc 5.3.1,clang 3.8.0并且intel编译器16.0.3不会产生任何警告或错误.

我怀疑在C++ 14标准的3.4.3.2.2下,这应该是有效的而不是含糊不清的,但我不太确定.

编辑:此外,foo::baz mybaz只有clang报告一个模棱两可的错误.

c++ language-lawyer c++14 gcc6

13
推荐指数
1
解决办法
295
查看次数

是否可以将python @ click.option装饰器重复用于多个命令?

我有两个Python CLI工具,它们共享一组常用的click.options。目前,通用选项已重复:

@click.command()
@click.option('--foo', is_flag=True)
@click.option('--bar', is_flag=True)
@click.option('--unique-flag-1', is_flag=True)
def command_one():
    pass

@click.command()
@click.option('--foo', is_flag=True)
@click.option('--bar', is_flag=True)
@click.option('--unique-flag-2', is_flag=True)
def command_two():
    pass
Run Code Online (Sandbox Code Playgroud)

是否可以将通用选项提取到可以应用于每个功能的单个装饰器中?

python python-click

11
推荐指数
3
解决办法
639
查看次数

如何为装饰器指定泛型类型的别名

考虑绑定到某些类的类型化装饰器的示例

import unittest
from typing import *

T = TypeVar("T", bound=unittest.TestCase)

def decorate(func: Callable[[T], None]) -> Callable[[T], None]:
    def decorated_function(self: T) -> None:
        return func(self)
    return decorated_function
Run Code Online (Sandbox Code Playgroud)

现在我什至有一个生成器来创建这些装饰器并想要速记这些装饰器。我对存储装饰器的变量使用什么类型(省略生成器的简化示例)。

my_decorate: Callable[[Callable[[T], None]], Callable[[T], None]] = decorate
Run Code Online (Sandbox Code Playgroud)

这可行,但很笨拙。所以问题是:

如何为该类型别名以避免编写完整签名?


不起作用的事情:

TD = Callable[[Callable[[T], None]], Callable[[T], None]]
my_decorate: TD[T] = decorator_variable
Run Code Online (Sandbox Code Playgroud)

给出错误

error: Type variable "mypytest.T" is unbound
note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
note: (Hint: Use "T" in function signature …
Run Code Online (Sandbox Code Playgroud)

python mypy python-typing

11
推荐指数
1
解决办法
542
查看次数

为什么perf有这么高的上下文切换?

我试图了解linux perf,发现一些非常令人困惑的行为:

我写了一个简单的多线程示例,其中一个线程固定到每个核心; 每个线程在本地运行计算,并且不相互通信(见test.cc下文).我在想这个例子应该有非常低的(如果不是零)上下文切换.但是,使用linux perf来分析示例显示了数千个上下文切换 - 远远超出了我的预期.我进一步分析了linux命令sleep 20以进行比较,显示更少的上下文切换.

此个人资料结果对我没有任何意义.什么导致如此多的上下文切换?

> sudo perf stat -e sched:sched_switch ./test
 Performance counter stats for './test':

                 6,725  sched:sched_switch                                          

      20.835 seconds time elapsed

> sudo perf stat -e sched:sched_switch sleep 20

 Performance counter stats for 'sleep 20':

                 1      sched:sched_switch                                          

      20.001 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

要重现结果,请运行以下代码:

perf stat -e context-switches sleep 20
perf stat -e context-switches ./test
Run Code Online (Sandbox Code Playgroud)

要编译源代码,请输入以下代码:

g++ -std=c++11 -pthread -o test test.cc
Run Code Online (Sandbox Code Playgroud)
// test.cc
#include <iostream>
#include <thread>
#include <vector> …
Run Code Online (Sandbox Code Playgroud)

c++ linux perf

9
推荐指数
2
解决办法
226
查看次数