Показать сообщение отдельно
Старый 29.11.2011, 18:09   #53
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Что-то я не смог избавиться от "оптимизаций компилятором", которые ухудшили результат получения данных при ordered и random индексах..

UPD: получилось.

Intel Pentium 4 3.00 Ghz

UPD2:
Вот такие результаты:
array size: 512 * 128 * 512 = 33554432
 --- Multidimensional
allocate:               25.945ms
fill:                   8221.827ms
get Ordered:            6834.768ms
get Random Order:       10833.646ms
 --- Flattened
allocate:               39.469ms
fill:                   985.824ms
get Ordered:            5357.747ms
get Random Order:       2922.386ms
 --- Jagged
allocate:               3119.915ms
fill:                   328.575ms
get Ordered:            6037.242ms
get Random Order:       8589.737ms
И вот такие результаты на более малого размера объём:
array size: 256 * 64 * 256 = 4194304
 --- Multidimensional
allocate:               2.107ms
fill:                   99.551ms
get Ordered:            96.638ms
get Random Order:       401.702ms
 --- Flattened
allocate:               0.201ms
fill:                   50.118ms
get Ordered:            49.65ms
get Random Order:       281.263ms
 --- Jagged
allocate:               39.366ms
fill:                   39.935ms
get Ordered:            50.619ms
get Random Order:       390.059ms
Заметьте, что в более малого объёма, как раз есть оптимизация на основе сортировки, а в большом нету..
Это случаем не потому что там идёт какое-то разбиение участка памяти на куски из-за слишком больших размеров?

Вот код обновил:
using System;
using System.Diagnostics;
using System.Threading;

namespace 
speedTest {
    static class 
Program {
        public 
struct index {
            public 
int x, y, z;
        };

        static 
int Main() {
            
long elapsed, number;
            
int width  = 256;
            
int height = 64;
            
int depth  = 256;
            
int volume = width * height * depth;

            
Console.WriteLine("array size: {0} * {1} * {2} = {3}", width, height, depth, volume);

            
index[] indicesOrdered = new index[volume];
            
index[] indicesRandom = new index[volume];

            { 
// fill up get values
                
Random rnd = new Random();
                
int i = 0;

                for (
int z = 0; z < depth; ++z) {
                    for (
int y = 0; y < height; ++y) {
                        for (
int x = 0; x < width; ++x) {
                            
indicesOrdered[i].x = z;
                            
indicesOrdered[i].y = y;
                            
indicesOrdered[i].z = x;

                            
indicesRandom[i].x = rnd.Next(width);
                            
indicesRandom[i].y = rnd.Next(height);
                            
indicesRandom[i].z = rnd.Next(depth);

                            ++
i;
                        }
                    }
                }
            }

            
Stopwatch timer = new Stopwatch();

            
Console.WriteLine(" --- Multidimensional");
            
Thread.Sleep(100);

            { 
// Multidimensional
                
int counter = 0;

                
timer.Restart();

                
int[,,] map = new int[width, height, depth];

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int x = 0; x < width; x++) {
                    for (
int y = 0; y < height; y++) {
                        for (
int z = 0; z < depth; z++) {
                            ++
counter;
                            
map[x, y, z] = counter;
                        }
                    }
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[indicesOrdered[i].x, indicesOrdered[i].y, indicesOrdered[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[indicesRandom[i].x, indicesRandom[i].y, indicesRandom[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
            }

            
Console.WriteLine(" --- Flattened");
            
Thread.Sleep(100);

            { 
// Flattened
                
int counter = 0;

                
timer.Restart();

                
int[] map = new int[width * height * depth];

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int x = 0; x < width; x++) {
                    for (
int y = 0; y < height; y++) {
                        for (
int z = 0; z < depth; z++) {
                            ++
counter;
                            
map[width * height * x + height * y + z] = counter;
                        }
                    }
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[width * height * indicesOrdered[i].x + height * indicesOrdered[i].y + indicesOrdered[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[width * height * indicesRandom[i].x + height * indicesRandom[i].y + indicesRandom[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
            }

            
Console.WriteLine(" --- Jagged");
            
Thread.Sleep(100);

            { 
// Jagged
                
int counter = 0;

                
timer.Restart();

                
int[][][] map = new int[width][][];
                for (
int y = 0; y < width; ++y) {
                    
map[y] = new int[height][];

                    for (
int z = 0; z < height; ++z) {
                        
map[y][z] = new int[depth];
                    }
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("allocate: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int x = 0; x < width; x++) {
                    for (
int y = 0; y < height; y++) {
                        for (
int z = 0; z < depth; z++) {
                            ++
counter;
                            
map[x][y][z] = counter;
                        }
                    }
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("fill: \t\t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[indicesOrdered[i].x][indicesOrdered[i].y][indicesOrdered[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Ordered: \t\t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
                
timer.Restart();

                for (
int i = 0; i < volume; ++i) {
                    
number = map[indicesRandom[i].x][indicesRandom[i].y][indicesRandom[i].z];
                }

                
elapsed = timer.ElapsedTicks;
                
Console.WriteLine("get Random Order: \t{0}ms", Math.Round(elapsed * 1000f / Stopwatch.Frequency, 3));
            }
            
Console.Read();
            return 
0;
        }
    }
} 
(Offline)
 
Ответить с цитированием