我想知道是否有人可以考虑更好的解决方案来做这些事情。
我有一个32位格式的原始位图数据(RGBA)
我需要通过消除alpha分量来转换和以24位格式转置此数组。
此外,我需要通过对齐结果数组的第一部分中的红色成分,第一个1/3之后的绿色和2/3之后的蓝色来转换数据,因为我正在进行RLE压缩之后。
通过这种对齐,我有更好的压缩,因为更有可能在像素之间进行红色,绿色和蓝色组件对齐。
我使用不安全和固定的指针来做到这一点。我得到了像11ms这样的东西来处理8.3M的数组长度。它似乎很低,但我正在进行实时屏幕抓取,每个ms都在计算......
(我绕过了不安全和固定的字节*东西):
byte* actualpointeur = actual == (IntPtr)pd1 ? pd1 : pd2; // it s the pointer on my source 32bit array
// pd24b is a pointer to my reception array at the right size...
byte* redindexp = pd24b;
byte* greenindexp = pd24b+(datain24format.Length / 3);
byte* blueindexp = pd24b+((datain24format.Length / 3) * 2);
for (int i = 0; i < datalenght; i += 4, actualpointeur+=4, redindexp++, greenindexp++, blueindexp++)
{
*redindexp= *(actualpointeur);
*greenindexp = *(actualpointeur+1);
*blueindexp = *(actualpointeur+2);
}
更新
我已经通过使用int *而不是字节*完成了hans的建议,并将循环反转为从end到0(再次比较为零更快) 它有点好(首先算法在~32000个刻度中完成,第二个在~31000个刻度中完成)
// it s the pointer on my source 32bit array
int* actualpointeur = actual == (IntPtr)pd1 ? (int*)pd1 + (datalenght / 4) - 1 : (int*)pd2 + (datalenght / 4) - 1;
// pd24b is a pointer to my reception array at the right size...
byte* redindexp = (pd24b + (datain24format.Length / 3)) - 1;
byte* greenindexp = (pd24b + (datain24format.Length / 3) * 2) - 1;
byte* blueindexp = (pd24b + datain24format.Length) - 1;
for (int i = datalenght - 1; i >= 0; i -= 4, actualpointeur--, redindexp--, greenindexp--, blueindexp--)
{
*redindexp = (byte)*(actualpointeur);
*greenindexp = (byte)(*(actualpointeur) >> 8);
*blueindexp = (byte)(*(actualpointeur) >> 16);
}
更新2
循环展开16像素有PFM建议(没有数据长度测试)我现在得到5ms(~15000)这是一个很大的改进...超过16不再提供改进
我的新循环是:
for (int i = _DataLenght - 1; i >= 0; i -= 64, actualpointeur-=16,redindexp-=16,greenindexp-=16,blueindexp-=16)
{
*redindexp = (byte)*(actualpointeur);
*greenindexp = (byte)(*(actualpointeur) >> 8);
*blueindexp = (byte)(*(actualpointeur) >> 16);
*(redindexp-1) = (byte)*(actualpointeur-1);
*(greenindexp-1) = (byte)(*(actualpointeur-1) >> 8);
*(blueindexp-1) = (byte)(*(actualpointeur-1) >> 16);
...
*(redindexp - 15) = (byte)*(actualpointeur - 15);
*(greenindexp - 15) = (byte)(*(actualpointeur - 15) >> 8);
*(blueindexp - 15) = (byte)(*(actualpointeur - 15) >> 16);
}
我开始关注gpu ......