2

x、y オフセットで同じサイズまたはそれ以上のサイズのバッファーにコピーする、任意のサイズのイメージ バッファーがあります。色空間は BGRA です。私の現在のコピー方法は次のとおりです。

void render(guint8* src, guint8* dest, uint src_width, uint src_height, uint dest_x, uint dest_y, uint dest_buffer_width) {
    bool use_single_memcpy = (dest_x == 0) && (dest_y == 0) && (dest_buffer_width == src_width);

    if(use_single_memcpy) {
        memcpy(dest, src, src_width * src_height * 4);
    }
    else {
        dest += (dest_y * dest_buffer_width * 4);
        for(uint i=0;i < src_height;i++) {
            memcpy(dest + (dest_x * 4), src, src_width * 4);
            dest += dest_buffer_width * 4;
            src += src_width * 4;
        }
    }
}

高速に実行されますが、それを改善して数ミリ秒余分に得るために何かできることがあるかどうかに興味がありました. アセンブリ コードを使用する場合は避けたいと思いますが、ライブラリを追加するつもりです。

4

2 に答える 2

1

あなたのuse_single_memcpyテストは制限が厳しすぎます。わずかな再配置により、dest_y == 0要件を削除できます。

void render(guint8* src, guint8* dest,
            uint src_width, uint src_height, 
            uint dest_x, uint dest_y,
            uint dest_buffer_width)
{
    bool use_single_memcpy = (dest_x == 0) && (dest_buffer_width == src_width);
    dest_buffer_width <<= 2;
    src_width <<= 2;
    dest += (dest_y * dest_buffer_width);

    if(use_single_memcpy) {
        memcpy(dest, src, src_width * src_height);
    }
    else {
        dest += (dest_x << 2);
        while (src_height--) {
            memcpy(dest, src, src_width);
            dest += dest_buffer_width;
            src += src_width;
        }
    }
}

また、ループをカウントダウン (より効率的である可能性があります) に変更し、役に立たない一時変数を削除し、繰り返し計算を解除しました。

SSE 組み込み関数を使用して一度に 4 バイトではなく 16 バイトをコピーすると、さらにうまくいく可能性がありますが、アライメントと 4 ピクセルの倍数について心配する必要があります。優れた memcpy 実装は、これらのことを既に行っているはずです。

于 2015-04-30T15:52:40.237 に答える