gpt4 book ai didi

c - 需要帮助优化函数调用

转载 作者:太空狗 更新时间:2023-10-29 15:55:35 26 4
gpt4 key购买 nike

我正在尝试实现图像处理功能。在这里:

typedef void (*AgFilter)(int*, int*, int*, float*);

static void filter(AndroidBitmapInfo* info, void* pixels, AgFilter func, void* params){

for(y = 0; y < height; y++){
for(x = 0; x < width; x++){
//initizalie r, g, b

func(&r, &g, &b, params); //here is the problem
}
}
}

我将此函数作为 func 传递:

static inline void brightness(int *r, int *g, int *b, float* param){
float add = param[0];

*r += add;
*g += add;
*b += add;
}

问题是它的运行速度极慢。好吧,我能理解。 但是 如果我不通过引用传递函数而是直接在filter 中编写我的函数(代替func 调用),它的运行速度要快得多。问题出在哪里?

附言请注意,它不是 c++

编辑

这个工作很快:

static void filter(AndroidBitmapInfo* info, void* pixels, int add){

for(y = 0; y < height; y++){
for(x = 0; x < width; x++){
//initizalie r, g, b
r += add;
g += add;
b += add;
}
}
}

最佳答案

调用函数需要时间。通常,您不会注意到,但您会调用该函数一百万次(全高清 1920x1080 图像大约两百万次)。现代相机创建 16 个百万像素图像。如果每次调用花费 1 us,则调用函数(不实际执行函数体)的累计时间将为 16

如何让它更快?一些建议:

  1. 不传递四个参数,而是使用结构:

     struct data { int r,g,b; float* param; }

    分配一次并重用它。现在您可以使用单个参数调用 func

  2. 内存布局可能有问题。 param 在内存中的任何地方。将其复制到 struct data 中:

     struct data { int r,g,b, add; }

    原因是 param 位于内存中的任何位置,这意味着它可能位于不同的缓存行中。如果您可以将所有数据放入一个 64 字节结构中,那么所有数据都将放入一个缓存行中,这可以极大地提升性能。

    但在您的情况下可能不是,因为您总是访问 param[0]。当您以随机方式访问数组时,这是一个更大的问题。

  3. 交换移位和位掩码操作:

     r = (int) ((line[x] & >> 16 ) & 0xFF);

    可以提供小幅提升,因为所有三种颜色现在都将被 0xFF 屏蔽,这允许编译器将常量移动一次到 CPU 寄存器。

  4. 调用函数时,所有的CPU寄存器都需要“保存/恢复”。那要花时间。当函数被内联时,编译器知道哪些 CPU 寄存器被丢弃并可以相应地进行优化。

    实际上,CPU寄存器并没有被保存(至少我已经很久没有看到了)。现代编译器只是假定在调用该函数后,所有这些都已更改。

  5. 请注意,inline 没有任何效果,因为您是通过引用传递函数而不是直接调用它。

  6. 使用线程。这对于并行化来说非常简单:在 1/N 的数据上运行函数 N 次(每个 CPU 内核一次)。这将使您获得大约 N 倍的性能提升。

关于c - 需要帮助优化函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12154693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com