Процедура MemoryFill - C#
Формулировка задачи:
Здравствуйте!
Имеется процедура заливки участка памяти некоторым значением:
Возможно ли ускорить эту процедуру, применив к ней какие-нибудь оптимизации, но без использования нативных библиотек?
Только средствами языка С#.
public unsafe void MemoryFill(int* ptr, int value, int count)
{
for(int i = 0; i < count; ++i)
{
ptr[i] = value;
}
}Решение задачи: «Процедура MemoryFill»
textual
Листинг программы
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Test
{
class Program
{
static unsafe void Main(string[] args)
{
int pass = 200000000;
int count = 100;
int value = 123456789;
IntPtr handle = Marshal.AllocHGlobal(count * sizeof(int));
int* ptr = (int*)handle;
Stopwatch sw1 = Stopwatch.StartNew();
for(int i = 0; i < pass; ++i)
{
MemoryFill(ptr, value, count);
}
sw1.Stop();
Stopwatch sw2 = Stopwatch.StartNew();
for(int i = 0; i < pass; ++i)
{
MemoryFillFast(ptr, value, count);
}
sw2.Stop();
Marshal.FreeHGlobal(handle);
Console.WriteLine(sw1.Elapsed);
Console.WriteLine(sw2.Elapsed);
Console.ReadKey();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static unsafe void MemoryFill(int* ptr, int value, int count)
{
for(int i = 0; i < count; ++i)
{
ptr[i] = value;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static unsafe void MemoryFillFast(int* ptr, int value, int count)
{
long longValue = (long)(uint)value << 32 | (uint)value;
long length = count << 2;
byte* dst = (byte*)ptr;
if(((int)dst & 4) != 0)
{
*(int*)dst = value;
dst += 4;
length -= 4;
}
long total = length >> 5;
while(total > 0)
{
((long*)dst)[0] = longValue;
((long*)dst)[1] = longValue;
((long*)dst)[2] = longValue;
((long*)dst)[3] = longValue;
dst += 32;
--total;
}
if((length & 16) != 0)
{
((long*)dst)[0] = longValue;
((long*)dst)[1] = longValue;
dst += 16;
}
if((length & 8) != 0)
{
*(long*)dst = longValue;
dst += 8;
}
if((length & 4) != 0)
{
*(int*)dst = value;
}
}
}
}