不安全的指针迭代和位图——为什么UInt64更快?我一直在做一些不安全的位图操作,发现增加指针的数量可以显着提高性能。我不知道这是为什么,即使你在循环中做更多的按位操作,还是少迭代指针更好。因此,例如,使用UInt64迭代超过32位像素,而不是使用UInt64迭代两个像素,并在一个循环中执行两次操作。以下通过读取两个像素并修改它们来工作(当然它会因奇数宽度图像而失败,但仅用于测试)。privatevoidremoveBlueWithTwoPixelIteration(){//想象一个带有数据的大图像Bitmapbmp=newBitmap(15000,15000,System.Drawing.Imaging.PixelFormat.Format32bppArgb);TimeSpan开始时间、结束时间;不安全{UInt64doublePixel;UInt32像素1;UInt32像素2;constintreadSize=sizeof(UInt64);constUInt64rightHalf=UInt32.MaxValue;PerformanceCounterpf=newPerformanceCounter("System","SystemUpTime");pf.NextValue();BitmapDatabd=bmp.LockBits(newRectangle(0,0,bmp.Width,bmp.Height),System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat);byte*image=(byte*)bd.Scan0.ToPointer();startTime=TimeSpan.FromSeconds(pf.NextValue());for(byte*line=image;line(readSize*8/2))>>8;//松散的最后8位(蓝色)pixel2=(UInt32)(doublePixel&rightHalf)>>8;//松散的最后8位(蓝色)*((UInt32*)pointer)=pixel1<<8;//putbackbutshift所以ARG回到原来的位置*((UInt32*)pointer+1)=pixel2<<8;//putbackbutshift让ARG回到原来的位置}}endTime=TimeSpan.FromSeconds(pf.NextValue());bmp.UnlockBits(bd);bmp.Dispose();}MessageBox.Show((endTime-startTime).TotalMilliseconds.ToString());}以下代码逐像素执行,比前一个慢70%:privatevoidremoveBlueWithSinglePixelIteration(){//想象一个带有数据的大图像Bitmapbmp=newBitmap(15000,15000,System.Drawing.Imaging.PixelFormat.Format32bppArgb);TimeSpan开始时间、结束时间;不安全{UInt32singlePixel;constintreadSize=sizeof(UInt32);PerformanceCounterpf=newPerformanceCounter("System","SystemUpTime");pf.NextValue();BitmapDatabd=bmp.LockBits(newRectangle(0,0,bmp.Width,bmp.Height),System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat);byte*image=(byte*)bd.Scan0.ToPointer();startTime=TimeSpan.FromSeconds(pf.NextValue());for(byte*line=image;line8;//looseB*((UInt32*)pointer)=singlePixel<<8;//向后调整ARG}}endTime=TimeSpan.FromSeconds(pf.NextValue());bmp.UnlockBits(bd);bmp.Dispose();}MessageBox.Show((endTime-startTime).TotalMilliseconds.ToString());}有人可以澄清为什么递增指针的操作比执行一些按位操作更昂贵吗?我正在使用.NET4框架,这些东西对C++真的吗?注意。32位与.64位两种方法比例相等,但两种方法在64位和32位之间有20%的速度差异?编辑:正如Porges和arul所建议的,这可能是因为更少的内存读取和更少的分支开销。EDIT2:经过一些测试,答案似乎是从内存中读取的时间更少:假设图像宽度可被5整除,您可以使用此代码快400%:[StructLayout(LayoutKind.Sequential,Pack=1)]structPixelContainer{公共UInt32pixel1;公共UInt32像素2;公共UInt32像素3;公共UInt32pixel4;公共UInt32pixel5;然后使用这个:intreadSize=sizeof(PixelContainer);//.....for(varpointer=line;pointer