小编B.S*_*.S.的帖子

使用枚举类的C++ 11标准符合位掩码

您可以使用枚举类实现标准符合(如n3242草案的17.5.2.1.3所述)类型安全位掩码吗?我读它的方式,类型T是一个位掩码,如果它支持|,&,^,〜,| =,&=和^ =运算符,你还可以做if(l&r)其中l和r是T类型.列表中缺少的是运算符!=和==并允许排序一个也可能想要重载<.

让操作员工作只是烦人的样板代码,但我不知道如何(l&r).至少下面的代码不能用GCC编译(除了极其危险,因为它允许错误的隐式转换为int):

enum class Foo{
    operator bool(){
        return (unsigned)*this;
    }
};
Run Code Online (Sandbox Code Playgroud)

编辑:我现在肯定知道枚举类不能有成员.实际问题如果(l&r)仍然存在.

c++ bitmask bit-fields c++11 enum-class

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

Singleton - 为什么要使用类?

就在前几天,我看到了使用所谓的单例模式的代码.意思是某些东西

class MySingleton{
public:
    void foo() { ... }
    static MySingleton&get_instance(){
        static MySingleton singleton;
        return singleton
    }
private:
    MySingleton(){ ... }
    ~MySingleton(){ ... }
    int bar;
};
Run Code Online (Sandbox Code Playgroud)

我确实想知道为什么会这样做:

  • 使实例可全局访问.
  • 确保该类的实例永远不会超过一个.

但是,我不明白为什么这种做事方式优于一些免费功能.我实施它的方式是放

namespace some_name{
    void foo();
}
Run Code Online (Sandbox Code Playgroud)

在标题和

namespace some_name{
    void foo(){
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在实现文件中.如果我需要初始化和/或清理,我要么添加一些必须显式调用或添加的函数

namespace{
    class Dummy{
        Dummy(){ ... }
        ~Dummy(){ ... }
    }dummy;
}
Run Code Online (Sandbox Code Playgroud)

进入实施文件.

我知道这是从语义的角度来看单例,但是我看到第一个变体在C++代码中使用得比第二个更常见.为什么?我认为第二个版本略胜一筹,所以我问自己是否遗漏了一些明显的东西.

  • 第二个版本实现起来更简单,更不容易出错.在第一个变体中,私有拷贝构造函数是为了证明这一点而缺少的.在第二个变体中,没有办法做这个错误.
  • 在第二个版本中,实现和接口更好地分开.在第一个中,必须在标题中声明所有私有成员.这样做的好处是,您可以从头开始重写实现,甚至不需要重新编译使用单例的任何内容.使用第一个变体时,即使只更改了轻微的实现细节,也很可能需要重新编译所有用户代码.
  • 两种情况都隐藏了实现细节.在使用私有的第一个变体中,在第二个变体中使用未命名的命名空间.

你能解释一下为什么每个人都使用第一个变种吗?我没有看到在C语言中做旧事情的单一优势.

c++ singleton

16
推荐指数
2
解决办法
3738
查看次数

伪造静态If在C++中

我正在测试各种优化的组合,对于这些,我需要一个静态的,如果在描述http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer启用并禁用特定的优化.if(const-expr)并不总是有效,因为某些优化涉及更改数据布局,而这在功能范围内无法完成.

基本上我想要的是这个:

template<bool enable_optimization>
class Algo{
  struct Foo{
    int a;
    if(enable_optimization){
      int b;
    }

    void bar(){
      if(enable_optimization){
        b = 0;
      }
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

(是的,在我的情况下,从数据布局中删除b的较小内存占用量是相关的.)

目前我正在使用非常糟糕的黑客伪装它.我正在寻找一种更好的方法.

档案啊

#ifndef A_H
#define A_H
template<class enable_optimization>
class Algo;
#include "b.h"
#endif
Run Code Online (Sandbox Code Playgroud)

文件bh(此文件是从Python脚本自动生成的)

#define ENABLE_OPTIMIZATION 0
#include "c.h"
#undef
#define ENABLE_OPTIMIZATION 1
#include "c.h"
#undef
Run Code Online (Sandbox Code Playgroud)

文件ch

template<>
class Algo<ENABLE_OPTIMIZATION>{
  struct Foo{
    int a;
    #if ENABLE_OPTIMIZATION
    int b;
    #endif

    void bar(){
      #if ENABLE_OPTIMIZATION
      b = 0;
      #endif
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

有谁知道更好的方法吗?从理论上讲,它可以使用模板元编程完成,起初我使用它.至少我使用它的方式是屁股的痛苦,并导致完全不可读和臃肿的代码.使用上面的hack可以显着提高生产力.

编辑:我有几个优化标志,这些互动.

c++ optimization static if-statement static-if

8
推荐指数
1
解决办法
1351
查看次数

使用OpenMP在x86上的原子最小值

OpenMP是否支持C++ 11的原子最小值?如果OpenMP没有可移植的方法:有没有办法使用x86或amd64功能?

在OpenMP规范中,我没有找到C++,但Fortran版本似乎支持它.有关详细信息,请参见v3.1的2.8.5.对于C++,它说明了

binop是+,*, - ,/,&,^,|,<<或>>之一.

但对Fortran来说,它说

intrinsic_procedure_name是MAX,MIN,IAND,IOR或IEOR之一.

如果您对更多上下文感兴趣:我正在寻找一个无互斥的方法来执行以下操作:

vector<omp_lock_t>lock;
vector<int>val;

#pragma omp parallel
{
  // ...
  int x = ...;
  int y = ...;
  if(y < val[x]){
    omp_set_lock(&lock[x]);
    if(y < val[x])
      val[x] = y;
    omp_unset_lock(&lock[x]);
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道您可以使用reduce算法计算最小值.我知道在某些情况下,这在很大程度上优于任何原子最小方法.但是,我也知道在我的情况下并非如此.

编辑:在我的情况下,一个选项稍微快一点

  int x = ...;
  int y = ...;
  while(y < val[x])
    val[x] = y;
Run Code Online (Sandbox Code Playgroud)

但这不是原子操作.

所有较新的GPU都具有此功能,我在CPU上遗漏了它.(请参阅OpenCL的atom_min.)

c++ x86 atomic openmp minimum

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

Java ArrayList真的比C++向量慢吗?

我不想开始另一个毫无意义的火焰战争,关于Java或C++是否是更好的语言.我想知道我为特定任务做的比较是否公平,测量数据是否正确.

我们需要决定是否将Java或C++用于我们的下一个项目.我在C++阵营,但我想为我的案子提供坚实的论据.我们的应用是特殊的,具有以下需求:

  • 该程序必须运行得相当快,并且具有合理的内存效率.我们不关心最近20%的表现.然而,10倍的性能差异是一个显示停止.
  • 我们有很多阵列.我们不知道他们的规模.因此,重要的是阵列可以在摊销的O(1)运行时间内在后面生长.
  • 数组中的元素由少量基本数据类型组成.典型的例子是整数或浮点数的元组.
  • 阵列可以变大.10 ^ 6个元素是标准的.我们有10 ^ 7个元素的应用程序,支持10 ^ 8会很棒.

我用C++和Java实现了一个玩具程序.首先,我介绍C++版本:

#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

struct Point{
        float x, y;
};

int main(int argc, char*argv[]){
        int n = atoi(argv[1]);

        vector<Point>arr;

        for(int i=0; i<n; ++i){
                Point p;
                p.x = i;
                p.y = i+0.5f;
                arr.push_back(p);
        }

        float dotp = 0;
        for(int i=0; i<n; ++i)
                dotp += arr[i].x * arr[i].y;

        cout << dotp << endl;
}
Run Code Online (Sandbox Code Playgroud)

接下来是执行相同操作的Java版本:

import java.util.*;

class Point{
        public float x, y;
} …
Run Code Online (Sandbox Code Playgroud)

c++ java arrays performance arraylist

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

忍者语言中是否有比 make 更快的东西?

我经常看到有人声称 Ninja 比 Make 更快,更擅长支持增量构建,并且更擅长并行化。这是实现质量问题还是 Ninja 语言中的某些内容可以实现这一点?

我知道 Ninja 和 Make 使用不同的文件格式来描述任务的依赖关系图。我知道 Make 允许使用比 ninja 更高级的功能,例如 globs。如果使用这样的高级功能,那么 Make 执行的任务比 Ninja 更复杂,我们不能指望 Make 更快。这是一种不公平的比较。

但是,假设不使用这种高级功能。没有通配符,没有模式规则,只是一遍又一遍地重复基本的“out_file: in_file1, in_file2\n\tcommand to build”。不使用这种高级功能会使 Make 和 Ninja 之间的竞争环境在他们执行的任务方面保持平衡。

我的理解是,如果我们以这种方式限制 Makefile,那么 Ninja 文件和 Makefile 可以很容易地相互转换。这样对吗?

为什么在有限的 Makefile 上执行的 Make 比 Ninja 慢?或者仅仅是标准 Make 实现没有针对以这种方式构建的 Makefile 进行优化的情况?

makefile build ninja

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

如何混合 32 位整数?或者:为什么没有_mm256_blendv_epi32?

我正在使用 AVX2 x86 256 位 SIMD 扩展。我想做一个 32 位整数组件 if-then-else 指令。在 Intel 文档中,此类指令称为 vblend。

Intel 内在指南包含函数 _mm256_blendv_epi8。这个功能几乎可以满足我的需要。唯一的问题是它适用于 8 位整数。不幸的是,文档中没有 _mm256_blendv_epi32 。我的第一个问题是:为什么这个功能不存在?我的第二个问题是:如何模仿?

经过一番搜索后,我发现 _mm256_blendv_ps 可以满足我对 32 位浮点的需求。此外,我还发现了转换函数 _mm256_castsi256_ps 和 _mm256_castps_si256,它们从整数转换为 32 位浮点数并返回。将这些放在一起给出:

inline __m256i _mm256_blendv_epi32 (__m256i a, __m256i b, __m256i mask){
    return _mm256_castps_si256( 
        _mm256_blendv_ps(
            _mm256_castsi256_ps(a),
            _mm256_castsi256_ps(b),
            _mm256_castsi256_ps(mask)
        ) 
    );
}
Run Code Online (Sandbox Code Playgroud)

虽然这看起来像 5 个函数,但其​​中 4 个只是美化的转换,还有一个直接映射到处理器指令上。因此,整个功能可以归结为一条处理器指令。

因此,真正尴尬的部分是,似乎有一个 32 位的 blendv,只是缺少相应的内在函数。

是否存在某种边界情况会导致惨败?例如,当整数位模式恰好表示浮点 NAN 时会发生什么?Blendv 是简单地忽略这一点还是会发出一些信号?

如果这有效:我是否正确,有 8 位、32 位和 64 位 Blendv,但缺少 16 位 Blendv?

c c++ sse intrinsics avx2

4
推荐指数
1
解决办法
2710
查看次数