【发布时间】:2010-12-28 22:46:25
【问题描述】:
我正在为跨平台 C 编写一个库,用于对网络摄像头图像进行各种处理。所有操作都是逐像素且高度可并行化的——例如应用位掩码、将颜色值乘以常数等。因此我认为我可以通过使用 SSE/SSE2 内在函数来获得性能。
但是,我遇到了数据格式问题。我的网络摄像头库将网络摄像头帧作为指针 (void*) 提供给包含 ABGR 或 BGR 格式的 24 位或 32 位字节像素的缓冲区。我一直将这些转换为 char* 以便 ptr++ 等行为正确。但是,所有 SSE/SSE2 操作都需要 __m128 或 __m64 数据类型中的四个整数或四个浮点数。如果我这样做(假设我已将缓冲区中的颜色值读入字符 r、g 和 b):
浮点像素[] = {(float)r, (float)g, {float)b, 0.0f};
然后加载另一个充满常量的浮点数组
浮点常量[] = {0.299, 0.587, 0.114, 0.0f};
将两个浮点指针都转换为 __m128,并使用 __mm_mul_ps 内在函数来执行 r * 0.299、g * 0.587 等 等等...没有整体性能提升,因为周围的所有洗牌都占用了太多时间!
对于如何快速有效地将这些字节像素值加载到 SSE 寄存器中,以便我真正通过对它们进行操作获得性能提升,是否有人有任何建议?
【问题讨论】:
-
是否需要进行浮点运算?还有 MMX,它适用于整数类型。
-
确实如此。如果您正在处理整数类型,则应使用整数 SIMD 指令,而不是浮点指令。
-
我不需要做任何浮点运算,所以你是对的,MMX 整数指令就足够了。
-
但是,如何有效地将原始字节像素缓冲区转换为整数以便我可以一次 SIMD 四个的问题仍然存在。
-
请记住为您的 __m128 和 __m64 数据类型使用对齐的缓冲区。至少在某些平台上,它们的对齐要求比 C 编译器所能保证的更严格。
标签: c optimization image-processing webcam