You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebAssembly中Rust多线程方框模糊代码优化求助

WebAssembly环境下Rust方框模糊的多线程实现与性能优化问题

我想给WebAssembly环境中的Rust方框模糊代码添加多线程功能以优化性能,但因Rust经验不足遇到了问题:无法从不同线程操作同一数据。我试过使用Rust标准库和rayon库,均未成功实现。同时希望得到该程序的性能优化建议,以下是我的代码:

#[wasm_bindgen]
pub fn box_blur_1d(context: CanvasRenderingContext2d,x: usize, y: usize, width: usize, height: usize) -> Clamped<Vec<u8>> {
    let i_data = context.get_image_data(0.0,0.0,1280.0,720.0).unwrap();
    let mut data: Clamped<Vec<u8>> = i_data.data();

    for row in y..y+height {
        blur_row(&mut data, row, x, width);
    }
    
    for column in x..x+width {
        blur_column(&mut data, column, y, height);
    }
    return data;
}

代码功能说明

这段代码实现图像方框模糊效果,步骤如下:

  • 将像素数据保存到Clamped<Vec<u8>>类型的data变量中
  • 遍历指定区域的每一行,调用blur_row处理行数据
  • 遍历指定区域的每一列,调用blur_column处理列数据
  • 返回处理后的像素数据

问题详情

无法从不同线程操作同一数据

以下是blur_row和blur_column函数的代码:

pub fn blur_row(data: &mut Clamped<Vec<u8>>, row: usize, x: usize, width: usize) {
    let mut r: usize = 0;
    let mut g: usize = 0;
    let mut b: usize = 0;
    let rowPosition: usize = row * 1280 * 4;

    let min: isize = x as isize - deviationBase as isize;

    for column in max(min,0) as usize..(x+deviationBase+1) {
        r += data[rowPosition + column * 4   ] as usize;
        g += data[rowPosition + column * 4 +1] as usize;
        b += data[rowPosition + column * 4 +2] as usize;
    }

    data[rowPosition + 0 + x * 4] = (r / (deviationBase + 1)) as u8;
    data[rowPosition + 1 + x * 4] = (g / (deviationBase + 1)) as u8;
    data[rowPosition + 2 + x * 4] = (b / (deviationBase + 1)) as u8;

    for column in x+1..deviationBase {
        r += data[rowPosition + (column + deviationBase) * 4    ] as usize;
        g += data[rowPosition + (column + deviationBase) * 4 + 1] as usize; 
        b += data[rowPosition + (column + deviationBase) * 4 + 2] as usize;
        data[rowPosition + column * 4    ] = (r / (diameter - deviationBase + column)) as u8;
        data[rowPosition + column * 4 + 1] = (g / (diameter - deviationBase + column)) as u8;
        data[rowPosition + column * 4 + 2] = (b / (diameter - deviationBase + column)) as u8;
    }

    for column in max(deviationBase, x+1)..x+width-deviationBase {
        r += data[rowPosition + (column + deviationBase) * 4    ] as usize;
        g += data[rowPosition + (column + deviationBase) * 4 + 1] as usize;
        b += data[rowPosition + (column + deviationBase) * 4 + 2] as usize;
        r -= data[rowPosition + (column - deviationBase) * 4    ] as usize; 
        g -= data[rowPosition + (column - deviationBase) * 4 + 1] as usize;
        b -= data[rowPosition + (column - deviationBase) * 4 + 2] as usize;
    
        data[rowPosition + column * 4    ] = (r / diameter) as u8;
        data[rowPosition + column * 4 + 1] = (g / diameter) as u8;
        data[rowPosition + column * 4 + 2] = (b / diameter) as u8;
    }

    for column in x+width-deviationBase..x+width {
        r -= data[rowPosition + (column- deviationBase) * 4    ] as usize;
        g -= data[rowPosition + (column- deviationBase) * 4 + 1] as usize;
        b -= data[rowPosition + (column- deviationBase) * 4 + 2] as usize;
        data[rowPosition + column * 4    ] = (r / (deviationBase + x + width - column)) as u8;
        data[rowPosition + column * 4 + 1] = (g / (deviationBase + x + width - column)) as u8;
        data[rowPosition + column * 4 + 2] = (b / (deviationBase + x + width - column)) as u8;
    }
}

pub fn blur_column(data: &mut Clamped<Vec<u8>>, column: usize, y: usize, height: usize) {
    let mut r: usize = 0;
    let mut g: usize = 0;
    let mut b: usize = 0;

    let columnPosition: usize = column*4;

    let min: isize = y as isize - deviationBase as isize;
    for row in max(min, 0) as usize..y+deviationBase+1 {
        r += data[row * 1280 * 4 + columnPosition + 0] as usize; 
        g += data[row * 1280 * 4 + columnPosition + 1] as usize; 
        b += data[row * 1280 * 4 + columnPosition + 2] as usize; 
    }
    data[columnPosition + 0 + y * 1280 * 4] = (r/(deviationBase+1)) as u8;
    data[columnPosition + 1 + y * 1280 * 4] = (g/(deviationBase+1)) as u8;
    data[columnPosition + 2 + y * 1280 * 4] = (b/(deviationBase+1)) as u8;

    for row in y+1..deviationBase {
        r += data[(row + deviationBase) * 1280 * 4 + columnPosition    ] as usize;
        g += data[(row + deviationBase) * 1280 * 4 + columnPosition + 1] as usize; 
        b += data[(row + deviationBase) * 1280 * 4 + columnPosition + 2] as usize;
        data[row * 1280 * 4 + columnPosition    ] =  (r / (diameter - deviationBase + row)) as u8;
        data[row * 1280 * 4 + columnPosition + 1] =  (g / (diameter - deviationBase + row)) as u8;
        data[row * 1280 * 4 + columnPosition + 2] =  (b / (diameter - deviationBase + row)) as u8;
    }

    for row in max(deviationBase, y+1)..y+height-deviationBase {
        r += data[(row + deviationBase) * 1280 * 4 + columnPosition   ] as usize;
        g += data[(row + deviationBase) * 1280 * 4 + columnPosition +1] as usize; 
        b += data[(row + deviationBase) * 1280 * 4 + columnPosition +2] as usize;
        r -= data[(row - deviationBase) * 1280 * 4 + columnPosition   ] as usize;
        g -= data[(row - deviationBase) * 1280 * 4 + columnPosition +1] as usize;
        b -= data[(row - deviationBase) * 1280 * 4 + columnPosition +2] as usize;

        data[row * 1280 * 4 + columnPosition    ] = (r / diameter) as u8;
        data[row * 1280 * 4 + columnPosition + 1] = (g / diameter) as u8;
        data[row * 1280 * 4 + columnPosition + 2] = (b / diameter) as u8;
    }

    for row in y+height-deviationBase..y+height {
        r -= data[(row - deviationBase) * 1280 * 4 + columnPosition   ] as usize;
        g -= data[(row - deviationBase) * 1280 * 4 + columnPosition +1] as usize;
        b -= data[(row - deviationBase) * 1280 * 4 + columnPosition +2] as usize;
        data[row * 1280 * 4 + columnPosition    ] = (r / (deviationBase + y + height - row)) as u8;
        data[row * 1280 * 4 + columnPosition + 1] = (g / (deviationBase + y + height - row)) as u8;
        data[row * 1280 * 4 + columnPosition + 2] = (b / (deviationBase + y + height - row)) as u8;
    }
}

内容的提问来源于stack exchange,提问作者Kevin Baving

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:15:44