.NET + Copier de grandes quantités d'astuces de mémoire


4

Autrefois, il y avait des astuces (souvent pour le blitting des framebuffers hors écran) pour copier de gros morceaux de mémoire d'un endroit à un autre. Maintenant que je travaille en C#, j'ai trouvé le besoin de déplacer un tableau d'octets (environ 32 Ko) d'un emplacement de mémoire à un autre environ 60 fois par seconde.

D'une certaine manière, je ne pense pas qu'un octet par octet dans une boucle for soit optimal ici.

Est-ce que quelqu'un connaît une bonne astuce pour faire ce genre de travail tout en restant dans le code purement géré? Si ce n'est pas le cas, je suis prêt à faire un P/Invoke ou à passer en mode non sécurisé, mais j'aimerais rester géré si je le peux pour des raisons de multiplateforme.

EDIT: Une partie du code d'étalonnage je l'ai écrit juste pour le plaisir:

octet par octet: 15.6192

4 octets par boucle: 15,6192

Bloc Copie: 0

Byte[] src = new byte[65535]; 
      Byte[] dest = new byte[65535]; 
      DateTime startTime, endTime; 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       for (int i = 0; i < src.Length; i++) 
       { 
        dest[i] = src[i]; 
       } 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("Byte by Byte: " + endTime.Subtract(startTime).TotalMilliseconds); 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       int i = 0; 
       while (i < src.Length) 
       { 
        if (i + 4 > src.Length) 
        { 
         // Copy the remaining bytes one at a time. 
         while(i < src.Length) 
         { 
          dest[i] = src[i]; 
          i++; 
         } 
         break; 
        } 

        dest[i] = src[i]; 
        dest[i + 1] = src[i + 1]; 
        dest[i + 2] = src[i + 2]; 
        dest[i + 3] = src[i + 3]; 

        i += 4;      
       } 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("4 Bytes per loop: " + endTime.Subtract(startTime).TotalMilliseconds); 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       Buffer.BlockCopy(src, 0, dest,0, src.Length); 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("Block Copy: " + endTime.Subtract(startTime).TotalMilliseconds); 
+1

System.Diagnostics.Stopwatch, classe très cool qui peut aider. 24 sept.. 082008-09-24 01:13:33

  0

Oui, le timing utilisant Now est plutôt inutile, sauf si vous faites beaucoup plus de répétitions que vous avez ici, pour obtenir le temps total utilisé. Now() ne fait que cocher toutes les 64 secondes sur la plupart des systèmes, donc tout votre benchmark établit que les deux premiers sont> 8 ms et les derniers <8 ms. 24 sept.. 082008-09-24 01:24:15

8

Je pense que vous pouvez compter sur Buffer.BlockCopy () Pour faire la bonne chose

http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx