小编Bas*_*sti的帖子

为什么这个包含rand()的C++ 11代码使用多个线程而不是一个?

我正在尝试新的C++ 11线程,但我的简单测试具有糟糕的多核性能.举个简单的例子,这个程序加上一些平方随机数.

#include <iostream>
#include <thread>
#include <vector>
#include <cstdlib>
#include <chrono>
#include <cmath>

double add_single(int N) {
    double sum=0;
    for (int i = 0; i < N; ++i){
        sum+= sqrt(1.0*rand()/RAND_MAX);
    }
    return sum/N;
}

void add_multi(int N, double& result) {
    double sum=0;
    for (int i = 0; i < N; ++i){
        sum+= sqrt(1.0*rand()/RAND_MAX);
    }
    result = sum/N;
}

int main() {
    srand (time(NULL));
    int N = 1000000;

    // single-threaded
    auto t1 = std::chrono::high_resolution_clock::now();
    double result1 = add_single(N);
    auto t2 …
Run Code Online (Sandbox Code Playgroud)

c++ performance multithreading c++11

41
推荐指数
3
解决办法
3882
查看次数

Python项目目录结构/ pytest麻烦

这应该是地球上最简单的问题,但即使经过大量的搜索和修补,我仍然在寻找一种"正确"的方式来构建目录结构并设法正确运行pytest等方面遇到了麻烦.

假设我有一个名为apple的程序.

|- README.md
|- apple
|   |-- __init__.py
|   |-- apple.py
| - tests
|   |-- test_everything.py
Run Code Online (Sandbox Code Playgroud)

apple.py包含一些函数,例如,让我们调用一个函数eat().该test_everything.py文件包含一些测试assert eat()=="foobar".好那么容易,但随后开始有趣:

  • __init__.py那苹果目录怎么样......对吗?空或应该在里面?
  • py.test从根目录调用是最佳做法吗?还是py.test tests
  • 很多项目都__init__.py在他们的测试目录中,但是在py.test文档中明确说明这是错误的.那么为什么上帝呢
  • test_everything.py文件顶部的内容是:a import apple还是from apple import *?或完全不同的东西
  • 你是通过eat()或调用函数apple.eat()吗?
  • 有些人甚至建议os.path.dirname在python中进行操作

这应该很容易,但我已经看到了上述的所有组合,甚至没有谈到tox和无数其他工具.然而,有一点点错误,你会被抛出一些ImportError: No module named 'apple'或其他一些时髦的错误.

什么是"正确"的方式?github等上的建议和现有代码遵循极为不同的约定.对于经验丰富的中档编码器,这应该更容易.

python path pytest

31
推荐指数
2
解决办法
8461
查看次数

特定C++随机数生成的Clang性能下降

使用C++ 11的随机模块,当使用std::mt19937(32和64位版本)与uniform_real_distribution(float或double,无关紧要)时,我遇到了奇怪的性能下降.与g ++编译相比,它的速度要慢一个数量级!

罪魁祸首不仅仅是mt发电机,因为它的速度很快uniform_int_distribution.并且这不是一个普遍的缺陷,uniform_real_distribution因为与其他发电机一样快default_random_engine.只是那个特定的组合很奇怪.

我对内在函数不是很熟悉,但Mersenne Twister算法或多或少都是严格定义的,所以实际上差异无法解释这个差异我猜?测量程序如下,但这是我在64位linux机器上的clang 3.4和gcc 4.8.1的结果:

gcc 4.8.1
runtime_int_default: 185.6
runtime_int_mt: 179.198
runtime_int_mt_64: 175.195
runtime_float_default: 45.375
runtime_float_mt: 58.144
runtime_float_mt_64: 94.188

clang 3.4
runtime_int_default: 215.096
runtime_int_mt: 201.064
runtime_int_mt_64: 199.836
runtime_float_default: 55.143
runtime_float_mt: 744.072  <--- this and
runtime_float_mt_64: 783.293 <- this is slow
Run Code Online (Sandbox Code Playgroud)

计划生成这个并尝试自己:

#include <iostream>
#include <vector>
#include <chrono>
#include <random>

template< typename T_rng, typename T_dist>
double time_rngs(T_rng& rng, T_dist& dist, int n){
    std::vector< typename T_dist::result_type > vec(n, 0); …
Run Code Online (Sandbox Code Playgroud)

c++ random clang mersenne-twister

22
推荐指数
1
解决办法
1711
查看次数

如何从单个通用对象创建“span&lt;std::byte&gt;”?

我有一个类型参数const T&,想将其转换为或任何吐出的std::span<const std::byte>魔法类型。std::as_bytes()

范围有许多构造函数,主要针对容器、数组等。但我似乎无法将单个对象变成这样的范围。我觉得这并不是一件没有道理的事情。

编辑:举个例子,什么不能编译:

const std::span<const std::byte> my_span(std::ranges::single_view{ object });
Run Code Online (Sandbox Code Playgroud)

c++ c++20

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

const ref 绑定到不同类型的基本原理?

我最近了解到可以将值分配给不同类型的引用。具体例子:

const std::optional<float>& ref0 = 5.0f;
const std::optional<float>& ref1 = get_float();
Run Code Online (Sandbox Code Playgroud)

这让我很惊讶。我当然希望这可以与非引用一起使用,但假设引用仅绑定到相同的类型。

我发现了 C++ 标准的一个很好的部分,其中讨论了其工作的各种方式: https: //eel.is/c++draft/dcl.init.ref#5。但我希望能得到一些见解:什么时候需要这样做?

最近这让我受伤的一个特殊场合是:

auto get_value() -> std::optional<float>{ /* ... */ }
const std::optional<float>& value = get_value();
// check and use value...
Run Code Online (Sandbox Code Playgroud)

后来我将函数的返回值更改为原始浮点数,预计所有引用类型的使用都会失败。他们没有。如果不注意,所有无用的检查代码都会留在原处。

c++

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

运行时的不同执行策略

在C++ 17中,algorithm标题中的许多函数现在可以采用执行策略.我可以举例来定义和调用这样的函数:

template <class ExecutionPolicy>
void f1(const std::vector<std::string>& vec, const std::string& elem, ExecutionPolicy&& policy) {
    const auto it = std::find(
        std::forward<ExecutionPolicy>(policy),
        vec.cbegin(), vec.cend(), elem
    );
}

std::vector<std::string> vec;
f1(vec, "test", std::execution::seq);
Run Code Online (Sandbox Code Playgroud)

但是我没有找到在运行时使用不同策略的好方法.例如,当我想根据某些输入文件使用不同的策略时.

我玩弄变种,但最后问题总是不同的类型std::execution::seq,std::execution::parstd::execution::par_unseq.

一个工作但繁琐的解决方案看起来像这样:

void f2(const std::vector<std::string>& vec, const std::string& elem, const int policy) {
    const auto it = [&]() {
        if (policy == 0) {
            return std::find(
                std::execution::seq,
                vec.cbegin(), vec.cend(), elem
            );
        }
        else if (policy == 1) {
            return std::find( …
Run Code Online (Sandbox Code Playgroud)

c++ parallel-processing

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

在配置文件引导优化之后嵌套for循环更快但具有更高的缓存未命中

我有一个程序,它的核心是一个二维数组的形式

std::vector<std::vector< int > > grid
Run Code Online (Sandbox Code Playgroud)

并且有一个简单的双循环进行,有点像这样:

for(int i=1; i<N-1; ++i)
    for(int j=1; j<N-1; ++j)
        sum += grid[i][j-1] + grid[i][j+1] + grid[i-1][j] + grid[i+1][j] + grid[i][j]*some_float;
Run Code Online (Sandbox Code Playgroud)

随着g++ -O3它的运行速度非常快,但为了进一步优化,我使用callgrind进行了分析,看到L1缓存约为37%,而LL为33%,考虑到计算的随机性,这是很多但不太令人惊讶.所以我做了一个配置文件引导优化a la

g++ -fprofile-generate -O3 ...
./program
g++ -fprofile-use -O3 ...
Run Code Online (Sandbox Code Playgroud)

并且程序运行速度提高了约48%!但令人费解的是:缓存未命中甚至增加了!L1数据缓存未命中率为40%,LL相同.

怎么可能?循环中没有条件可以优化预测并且缓存未命中甚至更高.然而它更快.

编辑:好的,这是sscce:http://pastebin.com/fLgskdQG .使用N来玩不同的运行时.编译通过

g++ -O3 -std=c++11 -sscce.cpp
Run Code Online (Sandbox Code Playgroud)

在linux下的gcc 4.8.1上.

使用上述命令进行轮廓引导优化.Callgrind的东西是用g ++ -g开关完成的valgrind --tool=callgrind --simulate-cache=yes ./sscce

c++ optimization gcc profiling

5
推荐指数
1
解决办法
327
查看次数

Numpy:将矩阵与向量数组相乘

我很难进入 numpy。我最终想要的是一个简单的由矩阵变换的向量的箭袋图。我已经阅读了很多次,只是将数组用于矩阵,这很公平。我有一个用于 x 和 y 坐标的网格

X,Y = np.meshgrid( np.arange(0,10,2),np.arange(0,10,1) )
a = np.array([[1,0],[0,1.1]])
Run Code Online (Sandbox Code Playgroud)

但即使在谷歌搜索并尝试了两个多小时之后,我也无法从a每个向量的矩阵乘法中得到结果向量。我知道 quiver 将分量长度作为输入,因此进入 quiver 函数的结果向量应该类似于np.dot(a, [X[i,j], Y[i,j]]) - X[i,j]x 分量,其中 i 和 j 在范围内迭代。

我当然可以在循环中对其进行编程,但是 numpy 有很多内置工具可以使这些矢量化的东西变得方便,我相信有更好的方法。

编辑:好的,这是循环版本。

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(10,10))

n=10
X,Y = np.meshgrid( np.arange(-5,5),np.arange(-5,5) )
print("val test", X[5,3])
a = np.array([[0.5,0],[0,1.3]])
U = np.zeros((n,n))
V = np.zeros((n,n))
for i in range(10):
    for j in range(10):
        product = np.dot(a, [X[i,j], Y[i,j]]) #matrix with vector …
Run Code Online (Sandbox Code Playgroud)

numpy scipy

5
推荐指数
2
解决办法
6215
查看次数

改变React阵列状态比克隆它更好/更快的方式?

每当React类具有一个或包含数组的状态对象时,更新该状态会感觉很尴尬.通常我做的是

var newArrayThing = _.clone(this.state.arrayThing); //or slice()
newArrayThing[123] = 42; //update stuff
this.setState({arrayThing: newArrayThing});
Run Code Online (Sandbox Code Playgroud)

是否有一种更好或更优雅的方式来处理这个我想念的?特别是因为如果阵列很大并且变化很小,我总觉得这是不必要的慢.所有这些都是为了简单的改变而复制 但国家不应该直接编辑似乎是口头禅.

Facebook文档提到了Immutability Helpers,但它们似乎比这更加遥远.

reactjs

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

减少 .git 目录中的文件数量

我正在将 git 用于一个中型项目:约 800 次提交,可能有 100 个左右的文件。我的 .git 文件夹有 18.8mb(据我所知,似乎是按照包含的文件大小的顺序排列)和 5586 个文件。这似乎太过分了——我什至会这么说,这很可笑。

许多文件在文件系统上都很困难,如果您必须同步该文件夹,则更加困难。事情就应该这样吗?有办法降低吗?我处理此类问题的天真方法是将所有需要的文件放入同一类型的存档中。

git

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