小编Ste*_*Lin的帖子

易失性但不受限制的读数会产生无限期陈旧的价值吗?(在真实的硬件上)

在回答这个问题时,关于OP的情况的另一个问题出现了,我不确定:它主要是处理器架构问题,但也有关于C++ 11内存模型的连锁问题.

基本上,由于以下代码(为简单起见略微修改),OP的代码在更高的优化级别上无限循环:

while (true) {
    uint8_t ov = bits_; // bits_ is some "uint8_t" non-local variable
    if (ov & MASK) {
        continue;
    }
    if (ov == __sync_val_compare_and_swap(&bits_, ov, ov | MASK)) {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

__sync_val_compare_and_swap()GCC的原子CAS 在哪里内置.GCC(合理地)在进入循环之前bits_ & mask检测到的情况下将其优化为无限循环,true完全跳过CAS操作,因此我建议进行以下更改(可行):

while (true) {
    uint8_t ov = bits_; // bits_ is some "uint8_t" non-local variable
    if (ov & MASK) {
        __sync_synchronize();
        continue;
    }
    if (ov == __sync_val_compare_and_swap(&bits_, ov, ov | MASK)) {
        break;
    } …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic volatile c++11

28
推荐指数
1
解决办法
1060
查看次数

强制GCC执行memcpy运行时大小检查的循环非开关?

有没有什么可靠的办法迫使海湾合作委员会(或编译器)中分解出运行时的大小检查memcpy()在循环外(如该尺寸不编译时间常数,但环内常数),专门为各相关尺寸范围内环路而不是反复检查其中的大小?

这是一个测试案例,从这里报告的性能回归中减少了一个开源库,该库设计用于大数据集的高效内存中分析.(回归恰好是因为我的一个提交...)

原始代码在Cython中,但我已将其简化为纯C代理,如下所示:

void take(double * out, double * in,
          int stride_out_0, int stride_out_1,
          int stride_in_0, int stride_in_1,
          int * indexer, int n, int k)
{
    int i, idx, j, k_local;
    k_local = k; /* prevent aliasing */
    for(i = 0; i < n; ++i) {
        idx = indexer[i];
        for(j = 0; j < k_local; ++j)
            out[i * stride_out_0 + j * stride_out_1] =
            in[idx * stride_in_0 + j * stride_in_1];
    }
}
Run Code Online (Sandbox Code Playgroud)

步伐是可变的; 一般来说,数组甚至不能保证是连续的(因为它们可能是较大数组的非连续切片.)但是,对于c连续数组的特殊情况,我已将上述内容优化为以下内容: …

c c++ performance memcpy compiler-optimization

28
推荐指数
1
解决办法
1719
查看次数

GCC(/ Clang):使用相同的指令合并函数(COMDAT折叠)

好奇的是,GCC或Clang工具集目前是否实现了相同的MSVC 相同的COMDAT折叠(ICF)?如果没有,有什么计划吗?除了旧的GCC邮件列表消息之外,我似乎无法找到关于该主题的任何最新权威链接.

如果不是,这是否意味着不同类型的模板实例化在结果二进制文件中始终是不同的函数(在它们没有完全内联的情况下),即使它们是二进制兼容的,或者是否存在其他机制来处理它在其他一些水平?

此外,有没有人发现ICF在最大限度地减少实际可执行文件的大小方面有很大的不同?我没有任何大型MSVC项目可以方便地进行测试.(我猜它只是真的有帮助,如果你碰巧在许多不同的vtable-layout兼容类型上实例化模板.)

最后,是否符合C++ 11标准的两个函数指针指向不同的函数,以便在运行时进行相等比较?这个链接似乎意味着它不是,但它适用于C99.编辑:发现此主题的上一个问题

linker gcc templates clang compiler-optimization

27
推荐指数
1
解决办法
5343
查看次数

子对象边界上的指针算法

以下代码(跨子对象边界执行指针运算)是否具有明确定义的行为,适用T于它编译的类型(在C++ 11中,不一定必须是POD)或其任何子集?

#include <cassert>
#include <cstddef>

template<typename T>
struct Base
{
    // ensure alignment
    union
    {
        T initial;
        char begin;
    };
};

template<typename T, size_t N>
struct Derived : public Base<T>
{
    T rest[N - 1];
    char end;
};

int main()
{
    Derived<float, 10> d;
    assert(&d.rest[9] - &d.initial == 10);
    assert(&d.end - &d.begin == sizeof(float) * 10);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

LLVM在内部向量类型的实现中使用上述技术的变体,该内部向量类型被优化以最初将堆栈用于小型阵列,但是在初始容量上切换到堆分配的缓冲区.(之所以做这种方式是不是从这个例子清楚,但显然是要减少模板代码膨胀,这是更清楚,如果你去翻代码.)

注意:在任何人抱怨之前,这并不是他们正在做的事情,可能是他们的方法比我在这里给出的标准更符合标准,但我想询问一般情况.

显然,它在实践中有效,但我很好奇,如果标准中的任何内容保证是这样的话.考虑到N3242/expr.add,我倾向于拒绝.

当减去指向同一数组对象的元素的两个指针时,结果是两个数组元素的下标的差异...此外,如果表达式P指向数组对象的元素或者指向最后一个元素的元素对于数组对象,并且表达式Q指向同一数组对象的最后一个元素,表达式((Q)+1) - (P)具有与((Q) - (P))+ 1相同的值,并且as …

c++ pointers pointer-arithmetic language-lawyer c++11

24
推荐指数
1
解决办法
821
查看次数

给定代表性字符串有限列表的正则表达式的语法推断?

我正在分析一个大型公共数据集,其中包含大量冗长的人类可读字符串,这些字符串是由一些常规(在形式语言理论意义上)语法明确生成的.

一个接一个地查看这些字符串集来查看模式并不太难; 不幸的是,大约有24,000个这些独特的字符串分为33个类别和1714个子类别,因此手动执行此操作有点痛苦.

基本上,我正在寻找一个现有的算法(最好使用现有的参考实现)来获取任意的字符串列表,并尝试推断一些可用于生成的正则表达式的最小化(对于一些合理的最小化定义)它们(即从该语法生成​​的语言中推导出一组有限字符串中的常规语法).

我已经考虑过重复贪婪最长的常见子串消除,但这只是到目前为止,因为除了完全匹配之外它不会崩溃,所以不会检测到,例如,在特定位置的变化数字串的常见模式语法.

暴力强迫任何不会脱离常见子串消除的东西是可能的,但可能在计算上不可行.(另外,我想过这个问题,有可能是一个"阶段排序"和/或子淘汰"当地最低"的问题,因为你可能会做出最终迫使最终语法贪婪的字符串匹配要少压缩/即使它看起来是最好的减少最小).

regex language-agnostic grammar automata dfa

21
推荐指数
1
解决办法
1816
查看次数

C++:类特化是一个符合标准的编译器的有效转换?

希望这对StackOverflow的问题不太专业:如果是,可以在其他地方迁移,请告诉我......

很久以前,我写了一篇本科毕业论文提出了C++和相关语言的各种devirtualization技术,一般是根据代码路径(有点像模板)预编译专业化的想法,但与检查,以选择正确的专长是在情况下,运行时选择它们不能在编译时选择(因为模板必须是).

(非常)基本的想法类似于以下内容...假设你有一个类C如下的类:

class C : public SomeInterface
{
public:
    C(Foo * f) : _f(f) { }

    virtual void quack()
    {
        _f->bark();
    }

    virtual void moo()
    {
        quack(); // a virtual call on this because quack() might be overloaded
    }

    // lots more virtual functions that call virtual functions on *_f or this

private:
    Foo * const _f; // technically doesn't have to be const explicitly
                    // as long as it can be proven not be modified
}; …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction virtual-functions vtable compiler-optimization

18
推荐指数
1
解决办法
379
查看次数

为什么std :: result_of将(不相关的)函数类型作为类型参数?

我意识到"为什么事情就像他们一样"问题通常不是最好的,但是很多人都在调整标准委员会讨论,所以我希望这可以在事实上得到回答,因为我对于什么是合法的好奇答案是.

基本上,我std::result_of第一次看到它时花了很长时间才弄清楚模板签名是怎么回事:我认为这是一个我从未见过的模板参数的全新构造.

template< class F, class... ArgTypes >
class result_of<F(ArgTypes...)>;
Run Code Online (Sandbox Code Playgroud)

经过一段时间的思考,我意识到这实际上是什么:F(ArgTypes...)是一个函数类型,但它不是正在评估结果类型的函数的类型(只是F):它是一个带ArgTypes...参数和返回类型的函数的类型F.

这不是......奇怪吗?有点hackish?有没有人知道委员会是否讨论过任何替代方案,例如,以下......

template< class F, class... ArgTypes >
class result_of<F, ArgTypes...>;
Run Code Online (Sandbox Code Playgroud)

我想有可能的情况是第二个结构不能像第一个结构那样容易使用,但是哪个?

我不是试图对此作出判断,但只是在我第一次看到它时,这对我来说是合法的混淆,所以我很好奇是否有充分的理由.我意识到答案的一部分可能只是"因为Boost这样做了",但仍留下剩下的(事实)问题......

  • 是否存在技术原因Boost选择此语法来编码类型信息而不是任何替代方案?

  • C++ 11委员会是否有任何关于如何将其标准化的讨论,因为无论如何std::result_of都可以decltype相当容易地实现?

c++ boost std c++11

18
推荐指数
2
解决办法
1837
查看次数

将一维数组重新整形为多维数组

考虑到整个C++ 11标准,任何符合要求的实现是否有可能成功完成下面的第一个断言,但后者失败了?

#include <cassert>

int main(int, char**)
{  
    const int I = 5, J = 4, K = 3;
    const int N = I * J * K;

    int arr1d[N] = {0};
    int (&arr3d)[I][J][K] = reinterpret_cast<int (&)[I][J][K]>(arr1d);
    assert(static_cast<void*>(arr1d) ==
           static_cast<void*>(arr3d)); // is this necessary?

    arr3d[3][2][1] = 1;
    assert(arr1d[3 * (J * K) + 2 * K + 1] == 1); // UB?
}
Run Code Online (Sandbox Code Playgroud)

如果不是,这在技术上是不是UB,并且如果第一个断言被删除,那么答案是否会改变(reinterpret_cast保证在这里保留地址?)?另外,如果重塑是在相反方向(3d到1d)或从6x35阵列到10x21阵列完成的,该怎么办?

编辑:如果答案是因为这是UB reinterpret_cast,是否还有一些其他严格遵守的重塑方式(例如,static_cast来自/来自中间人void *)?

c++ multidimensional-array language-lawyer c++11

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

Clang vs. GCC:通过合格/不合格的名称为全球职能提供帮助

我正在试图弄清楚是否要提交针对Clang,GCC或两者的错误报告(我已经针对Clang主干和GCC 4.7.2进行了测试:如果有人可以对GCC主干进行验证,这会有所帮助):

基本上,以下代码三行文件-fsyntax-only在默认和C++ 11模式下编译良好:

class A {
    friend void f();
};
Run Code Online (Sandbox Code Playgroud)

请注意,之前没有声明f(),但这显然是可以的.

但是,Clang(但不是GCC)拒绝接受以下内容:

class A {
    friend void ::f();
};
Run Code Online (Sandbox Code Playgroud)

Clang的错误是"在指定的范围内找不到类型'void()'的函数'f',但我在标准中找不到任何理由来处理这种情况与前一种不同,所以我认为这是一个错误; 我可能错了(我正在阅读N3242,但是,AFAIK是C++ 11之前的最后一次公开选秀).

然而,下一个例子被GCC而不是Clang拒绝:

void f() { }

void g()
{
    class A {
        friend void ::f();
    };
}
Run Code Online (Sandbox Code Playgroud)

来自GCC的错误是"没有事先声明的本地类中的朋友声明'void f()'",这似乎没有意义,因为void ::f()应该引用f()声明的全局命名空间.(没关系 - friend来自本地班级的全局功能是荒谬的,它似乎并非违法......)

最后,最后一个例子被Clang和GCC拒绝:

void g()
{
    class A {
        friend void ::f();
    };
}
Run Code Online (Sandbox Code Playgroud)

错误是本地类中的"friend declaration'void f()',而没有事先声明"和"分别在指定的范围"中没有找到名为'f'且类型为'void()'的函数.现在,从11.4p11开始,似乎有一些理由拒绝在本地类中拒绝朋友对先前未声明函数的声明,但该段实际上是:

如果友元声明出现在本地类(9.8)中并且指定的名称是非限定名称,则会查找先前声明,而不考虑最内部封闭非类作用域之外的作用域.对于朋友函数声明,如果没有事先声明,该程序是不正确的...

本声明的非法性显然是基于本段的第二句,但我不清楚该句是否适用于具有合格名称的情况,如本案所用.(可以说,无论是否使用"非限定名称",整个段落都适用于"本地类",并且"和指定的名称是非限定名称"条款仅适用于所描述的查找在第一句中,但它似乎是一个延伸...我想象这是一种可能性的唯一原因是因为两个编译器都拒绝它.)

无论如何,据我所知,所有这四个案件(无论他们是否合理)都应该是合法的; 即使不是,Clang和GCC中至少有一个在第二和第三种情况下是错误的.任何人都可以在我的逻辑中发现错误吗?

第三和第四个案件无疑是荒谬的; 但我可以看到第二个案例打破某人的有效和有用的代码,所以我有点惊讶它从未被捕获过,如果它确实是一个错误.

c++ gcc clang language-lawyer

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

ARM C++ ABI:构造函数/析构函数返回值

我一直在阅读Clang源代码,发现了一些关于ARM C++ ABI的有趣内容,我似乎无法理解其中的理由.从ARM ABI文档的在线版本:

这个ABI要求C1和C2构造函数返回(而不是void函数),这样C3构造函数可以尾调用C1构造函数,C1构造函数可以尾调用C2.

(对于非虚拟析构函数也是如此)

我不知道是什么C1,C2以及C3在这里引用.这一节,就是要的§3.1.5从通用(即安腾)ABI的修改,而这部分(至少在这个网上verison)简单地说:

构造函数返回void结果.

无论如何,我真的无法弄清楚这是什么目的:如何使构造函数返回允许尾部调用优化,以及在什么情况下?

到目前为止,我可以说,构造函数可以尾部调用另一个具有相同this返回值的唯一时间是具有单个基类的派生类,一个简单的构造函数体,没有具有非平凡构造函数的成员,并且没有虚拟表指针.实际上,使用void返回来优化尾部调用似乎实际上更容易,而不是更难,因为这样可以消除单个基类的限制(在多基类的情况下,this指针从最后调用的构造函数不会是this派生对象的指针).

我在这里错过了什么?ARM调用约定是否有this必要使返回成为必要?

c++ arm abi

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