这是用alloca()

时间:2015-10-19 23:48:02

标签: c++ memory-management

我认为我发现alloca()很好地用来分配内存。此代码的目的是对图像执行中值滤波。我正在使用openmp所以我不想使用任何可能导致异常的事情来分配内存。此外,每个数组都需要在线程本地,这使事情变得更复杂。我想出的解决方案是使用alloca()在堆栈上分配数组,因为这应该比new或malloc快得多。我只是想知道你们对它的看法。如果您有任何加速此功能的建议,请告诉我,因为中值滤波器有点慢。

#include "../../Image.hpp"
#include <utility>
#include <cstdlib>

using namespace cpimg;

Image Image::median_filter(int radius) const
{
    img_assert(radius > 0, "Invalid radius.");

    Image result(w, h);
    int n = radius * 2 + 1;

    auto median = [this, radius, n](dim_t r, dim_t c)
    {
        int size = 0;

        dim_t istart = r - radius;
        dim_t jstart = c - radius;
        dim_t iend = r + radius;
        dim_t jend = c + radius;

        istart = istart < 0 ? 0 : istart;
        jstart = jstart < 0 ? 0 : jstart;
        iend = iend >= h ? h - 1 : iend;
        jend = jend >= w ? w - 1 : jend;

        int alloc = (iend - istart) * (jend - jstart) * sizeof(float);
        float* reds = (float*)alloca(alloc);
        float* greens = (float*)alloca(alloc);
        float* blues = (float*)alloca(alloc);

        for(dim_t i = istart; i < iend; i++)
        {
            for(dim_t j = jstart; j < jend; j++)
            {
                reds[size] = (*this)[i][j].red;
                greens[size] = (*this)[i][j].green;
                blues[size] = (*this)[i][j].blue;

                for(int k = size; k > 0 && reds[k - 1] > reds[k]; k--)
                    std::swap(reds[k], reds[k - 1]);
                for(int k = size; k > 0 && greens[k - 1] > greens[k]; k--)
                    std::swap(greens[k], greens[k - 1]);
                for(int k = size; k > 0 && blues[k - 1] > blues[k]; k--)
                    std::swap(blues[k], blues[k - 1]);
                size++;
            }
        }

        Pixel m;
        m.red = size % 2 ? reds[size / 2] : 0.5 * (reds[size / 2] + reds[size / 2 - 1]);
        m.green = size % 2 ? greens[size / 2] : 0.5 * (greens[size / 2] + greens[size / 2 - 1]);
        m.blue = size % 2 ? blues[size / 2] : 0.5 * (blues[size / 2] + blues[size / 2 - 1]);
        return m;
    };

    #pragma omp parallel for
    for(dim_t r = 0; r < h; r++)
    {
        for(dim_t c = 0; c < w; c++)
        {
            result[r][c] = median(r, c);
        }
    }

    return result;
}

0 个答案:

没有答案