c - 如何优化分配固定红利?

标签 c algorithm optimization integer-division

除以常数的优化由 gcc 很好地优化,这是众所周知的:)

现在我想知道除以常数是如何优化的。 gcc 没有帮助我,clang 也没有。

也许我不擅长搜索这些资料,但我找不到有关分频常数优化的资料。 (相比之下,常量除法介绍得很好。)

#include <stdio.h>

int f(int x)
{
    // can I optimize off the idiv opcode here?
    return 33659/x;
}

int main()
{
    int x;
    scanf("%d", &x);
    printf("%d", f(x));
    return 0;
}

编辑1:

#include <stdio.h>

#define DIVIDEND 33

void f ( unsigned int* arr, int n )
{
    for ( int i = 0; i < n ; i++ )
    {
        arr[i] = DIVIDEND / arr[i];
    }
}

int main()
{
    const int n = 1024;
    unsigned int buf[n];
    for ( int i = 0; i < n; i++ )
    {
        scanf ( "%u", buf + i );
    }
    f ( buf, n );
    for ( int i = 0; i < n; i++ )
    {
        printf ( "%d", buf[i] );
    }
    return 0;
}

使用 clang -O3 -march=native div.c -o div 优化后只展开循环,同时:

#include <stdio.h>

#define DIVIDEND 33
#define DIVISOR DIVIDEND

void f ( unsigned int* arr, int n )
{
    for ( int i = 0; i < n ; i++ )
    {
        //arr[i] = DIVIDEND / arr[i];
        arr[i] = arr[i] / DIVISOR;
    }
}

int main()
{
    const int n = 1024;
    unsigned int buf[n];
    for ( int i = 0; i < n; i++ )
    {
        scanf ( "%u", buf + i );
    }
    f ( buf, n );
    for ( int i = 0; i < n; i++ )
    {
        printf ( "%d", buf[i] );
    }
    return 0;
}

使用相同的命令行会产生一堆可怕的 AVX2 代码。 (记住除以常数改写成shift+m​​ul+add,可以向量化!)

编辑2: 感谢@user2722968!应用 RCPPS 将使程序更快。

这是我使用 RCPPS 进行快速恒定股息分配的实验性实现:

https://github.com/ThinerDAS/didactic-spoon/blob/master/div.c

但是,我不确定如何在没有大量开销的情况下使其更准确。

最佳答案

如果您可以针对“除以”触发非常好的优化,那么您可能会受益于使用 RCPPS 指令(确实使用 SSE/AVX)计算 x/33659 的倒数。

关于c - 如何优化分配固定红利?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44862898/

相关文章:

c - 定义全局变量,在 main 中得到不同的结果

ruby-on-rails - 使用递归(二进制转换器)在 Ruby 中将 base-10 转换为 base-2

optimization - 使用Logistic回归模型自动选择gcc编译器优化

C extern clock_t 变量在文件中未按预期工作;

c - 在 C 中处理 ldap_initalize 时出错

c++ - 如何在 Solaris 系统中以 C/C++ 编程方式获取进程信息?

java - 对具有许多相等值的数组进行排序java

algorithm - 频繁项集与关联规则——Apriori算法

.net - 使用 .NET Framework 4.0 dll 代替 2.0 dll 有什么优势吗?

optimization - 分支目标缓冲区检测到什么分支预测错误?