2013-07-24 2 views
0

Являются ли использование (не творениями) скорости динамических и классических многомерных массивов различными с точки зрения скорости?Разница в скорости динамических и классических многомерных массивов

Я имею в виду, например, когда я пытаюсь получить доступ ко всем значениям в трехмерном массиве с помощью циклов. Есть ли разница в скорости между массивами, создаваемыми как динамические и классические методы.

Когда я говорю "динамический трехмерный массив", я имею в виду matris_cos [kuanta] [d] [angle_scale] создается следующим образом.

matris_cos = new float**[kuanta]; 
for (int i = 0; i < kuanta; ++i) { 
    matris_cos[i] = new float*[d]; 

    for (int j = 0; j < d; ++j) 
    matris_cos[i][j] = new float[angle_scale]; 
} 

Когда я говорю "классический трехмерный массив", я имею в виду matris_cos [kuanta] [d] [angle_scale] просто создан, как это.

float matris_cos[kuanta][d][angle_scale]; 

Но, пожалуйста, обратите внимание, я не спрашиваю о скорости создания этих массивов. Я хочу получить доступ к значениям этих массивов через некоторые циклы. Есть ли разница в скорости, когда я пытаюсь получить доступ к значениям.

+2

Создайте две программы, по одному с каждым методом, и сравните их. Я сомневаюсь, что вы найдете хоть какую-то разницу. –

+1

Вам нужно иметь огромные данные, чтобы обнаружить такую ​​разницу. Кстати, многомерные массивы обычно хранятся в основном файле или в главном формате –

ответ

1

Массив указателей (для массивов указателей) потребует дополнительных уровней косвенности для доступа к случайному элементу, в то время как для многомерного массива потребуются основные арифметические операции (умножение и добавление указателя). На большинстве современных платформ косвенность, скорее всего, будет медленнее, если вы не используете кэш-ориентированные шаблоны доступа. Кроме того, все элементы многомерного массива будут смежными, что может помочь кешировать, если вы перебираете весь массив.

Независимо от того, измеряется ли это различие или нет, вы можете только измерить его.

Если дополнительная косвенность действительно оказаться узким местом, вы могли бы заменить указатели на массив из-с классом, чтобы представить многомерный массив с плоской решеткой:

class array_3d { 
    size_t d1,d2,d3; 
    std::vector<float> flat; 

public: 
    array_3d(size_t d1, size_t d2, size_t d3) : 
     d1(d1), d2(d2), d3(d3), flat(d1*d2*d3) 
    {} 

    float & operator()(size_t x, size_t y, size_t z) { 
     return flat[x*d2*d3 + y*d3 + z]; 
    } 
    // and a similar const overload 
}; 

Я считаю, что следующий стандарт C++ (ожидается в следующем году) будет включать массивы с динамическим размером, поэтому вы должны иметь возможность использовать многомерную форму во всех случаях.

1

Вы не сможете обнаружить какую-либо разницу между ними в типичном приложении, если только ваши массивы не огромны, и вы тратите много времени на чтение/запись, но тем не менее, есть разница.

float matris_cos[kuanta][d][angle_scale]; 

1) Память для этого многомерного массива будет непрерывной. В результате будет меньше промахов в кэше.
2) Массив потребует пространства только для самих поплавков.

matris_cos = new float**[kuanta]; 
for (int i = 0; i < kuanta; ++i) { 
    matris_cos[i] = new float*[d]; 

    for (int j = 0; j < d; ++j) 
     matris_cos[i][j] = new float[angle_scale]; 
} 

1) Память для этого многомерного массива выделяется блоками и, следовательно, гораздо реже будет смежной. Это может привести к промахам в кеше.
2) Этот метод требует пространства для указателей, а также самих поплавков.

Поскольку во втором случае существует косвенное направление, вы можете ожидать незначительную разницу в скорости при попытке получить доступ или изменить значения.

Напомним:

  • Второй случай использует больше памяти
  • Второй случай предполагает Косвенность
  • Второй случай не имеет гарантированное расположение кэша.