首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Clang的__restrict不一致吗?

Clang的__restrict不一致吗?
EN

Stack Overflow用户
提问于 2021-12-13 18:29:42
回答 1查看 260关注 0票数 5

我在编写高度“可矢量化”的代码,并注意到对于C++ __restrict关键字/扩展~,Clang的行为与GCC不同,甚至在一个简单的例子中也是不切实际的。

对于编译器生成的代码,减速大约为15倍(在我的具体情况下,而不是下面的例子)。

下面是代码(也可以在https://godbolt.org/z/sdGd43x75上获得):

代码语言:javascript
运行
复制
struct Param {
    int *x;
};

int foo(int *a, int *b) {
    *a = 5;
    *b = 6;
    // No significant optimization here, as expected (for clang/gcc)
    return *a + *b;
}

int foo(Param a, Param b) {
    *a.x = 5;
    *b.x = 6;
    // No significant optimization here, as expected (for clang/gcc)
    return *a.x + *b.x;
}

/////////////////////

struct ParamR {
    // "Restricted pointers assert that members point to disjoint storage"
    // https://en.cppreference.com/w/c/language/restrict, is restrict's 
    // interpretation for C can be used in C++ (for __restrict too ?) ?
    int *__restrict x;
};

int rfoo(int *__restrict a, int *__restrict b) {
    *a = 5;
    *b = 6;
    // Significant optimization here, as expected (for clang/gcc)
    return *a + *b;
}

int rfoo(ParamR a, ParamR b) {
    *a.x = 5;
    *b.x = 6;
    // No significant optimization here, NOT expected (clang fails?, gcc optimizes)
    return *a.x + *b.x;
}

int rfoo(ParamR *__restrict a, ParamR *__restrict b) {
    *a->x = 5;
    *b->x = 6;
    // No significant optimization here, NOT expected (clang fails?, gcc optimizes)
    return *a->x + *b->x;
}

C++ (__restrict)和C代码(使用std限制)都会发生这种情况。

如何让Clang理解指针总是指向不相交的存储?

EN

回答 1

Stack Overflow用户

发布于 2021-12-13 19:33:21

好像是个虫子。我不知道是否应该称它为bug,因为它确实为程序创建了正确的行为,假设它是优化器中的一个错失的机会。

我尝试了一些解决方法,唯一起作用的是始终将指针作为限制参数传递。就像这样:

代码语言:javascript
运行
复制
int rfoo(int *__restrict a, int *__restrict b) {
    *a = 5;
    *b = 6;
    // Significant optimization here, as expected (for clang/gcc)
    return *a + *b;
}

// change this:
int rfoo(ParamR a, ParamR b) {
    *a.x = 5;
    *b.x = 6;
    // No significant optimization here, NOT expected (clang fails?, gcc optimizes)
    return *a.x + *b.x;
}

// to this:
int rfoo2(ParamR a, ParamR b) {
    return rfoo(a.x, b.x);
}

来自clang 12.0.0的产出:

代码语言:javascript
运行
复制
rfoo(ParamR, ParamR):                       # @rfoo(ParamR, ParamR)
        mov     dword ptr [rdi], 5
        mov     dword ptr [rsi], 6
        mov     eax, dword ptr [rdi]
        add     eax, 6
        ret
rfoo2(ParamR, ParamR):                      # @rfoo2(ParamR, ParamR)
        mov     dword ptr [rdi], 5
        mov     dword ptr [rsi], 6
        mov     eax, 11
        ret

现在,这是非常不方便的,特别是对于更复杂的代码,但是如果性能差异如此之大和重要,并且您不能更改为gcc,这可能是在考虑做一些事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70339339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档