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
相关产品推荐
相关产品推荐

