더 빠른 것은 요소 선택 연산자를 사용하여 다중 배열 요소에 액세스하거나 반복자를 사용하여 다중 배열을 탐색하는 것입니다.Boost MultiArray에서 요소에 액세스하는 가장 빠른 방법
필자의 경우, 매번 multiarray의 모든 요소를 완전히 통과시켜야합니다.
더 빠른 것은 요소 선택 연산자를 사용하여 다중 배열 요소에 액세스하거나 반복자를 사용하여 다중 배열을 탐색하는 것입니다.Boost MultiArray에서 요소에 액세스하는 가장 빠른 방법
필자의 경우, 매번 multiarray의 모든 요소를 완전히 통과시켜야합니다.
boost::multi_array
의 모든 요소에 액세스하는 가장 빠른 방법은 data()
및 num_elements()
입니다.
data()
을 사용하면 기본 원시 스토리지 (배열의 데이터가 포함 된 인접한 블록)에 액세스 할 수 있으므로 여러 인덱스 계산이 필요하지 않습니다. multi_array
은 0과 다른 기준의 배열을 인덱싱 할 수 있습니다 이것은 더 복잡한 문제입니다.)
간단한 테스트를 제공합니다 : 기본 부스트 액세스 방법으로
g++ -O3 -fomit-frame-pointer -march=native (GCC v4.8.2)
Writing (index): 9.70651
Writing (data): 2.22353
Reading (index): 4.5973 (found 1)
Reading (data): 3.53811 (found 1)
clang++ -O3 -fomit-frame-pointer -march=native (CLANG v3.3)
Writing (index): 5.49858
Writing (data): 2.13678
Reading (index): 5.07324 (found 1)
Reading (data): 2.55109 (found 1)
범위 검사를 수행합니다. 제공된 인덱스가 배열에 정의 된 범위를 벗어나면 어설 션이 프로그램을 중단합니다. 범위 검사를 사용하지 않으려면 응용 프로그램에 multi_array.hpp
을 포함하기 전에 BOOST_DISABLE_ASSERTS
사전 처리기 매크로를 정의 할 수 있습니다.
이 많게 성능 차이를 줄이는 것이다
g++ -O3 -fomit-frame-pointer -march=native (GCC v4.8.2)
Writing (index): 3.15244
Writing (data): 2.23002
Reading (index): 1.89553 (found 1)
Reading (data): 1.54427 (found 1)
clang++ -O3 -fomit-frame-pointer -march=native (CLANG v3.3)
Writing (index): 2.24831
Writing (data): 2.12853
Reading (index): 2.59164 (found 1)
Reading (data): 2.52141 (found 1)
성능 차이가 증가 (즉 data()
가 빠르다) 치수 높은 번호
어쨌든 이러한 종류의 최적화는 실제 프로그램에서 측정 할 수있는 차이를 만들어 내지 않을 것입니다. 광범위한 테스트를 통해 병목 현상의 근원이라는 결론을 내리지 않는 한 걱정할 필요가 없습니다.
출처 :
#include <chrono>
#include <iostream>
// #define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
int main()
{
using array3 = boost::multi_array<unsigned, 3>;
using index = array3::index;
using clock = std::chrono::high_resolution_clock;
using duration = std::chrono::duration<double>;
constexpr unsigned d1(300), d2(400), d3(200), sup(100);
array3 A(boost::extents[d1][d2][d3]);
// Writing via index
const auto t_begin1(clock::now());
unsigned values1(0);
for (unsigned n(0); n < sup; ++n)
for (index i(0); i != d1; ++i)
for (index j(0); j != d2; ++j)
for (index k(0); k != d3; ++k)
A[i][j][k] = ++values1;
const auto t_end1(clock::now());
// Writing directly
const auto t_begin2(clock::now());
unsigned values2(0);
for (unsigned n(0); n < sup; ++n)
{
const auto sup(A.data() + A.num_elements());
for (auto i(A.data()); i != sup; ++i)
*i = ++values2;
}
const auto t_end2(clock::now());
// Reading via index
const auto t_begin3(clock::now());
bool found1(false);
for (unsigned n(0); n < sup; ++n)
for (index i(0); i != d1; ++i)
for (index j(0); j != d2; ++j)
for (index k(0); k != d3; ++k)
if (A[i][j][k] == values1)
found1 = true;
const auto t_end3(clock::now());
// Reading directly
const auto t_begin4(clock::now());
bool found2(false);
for (unsigned n(0); n < sup; ++n)
{
const auto sup(A.data() + A.num_elements());
for (auto i(A.data()); i != sup; ++i)
if (*i == values2)
found2 = true;
}
const auto t_end4(clock::now());
std::cout << "Writing (index): "
<< std::chrono::duration_cast<duration>(t_end1 - t_begin1).count()
<< std::endl
<< "Writing (data): "
<< std::chrono::duration_cast<duration>(t_end2 - t_begin2).count()
<< std::endl
<< "Reading (index): "
<< std::chrono::duration_cast<duration>(t_end3 - t_begin3).count()
<< " (found " << found1 << ")" << std::endl
<< "Reading (data): "
<< std::chrono::duration_cast<duration>(t_end4 - t_begin4).count()
<< " (found " << found2 << ")" << std::endl;
return 0;
}
왜 비교? 결과는 컴파일러, 플랫폼 등에 따라 달라질 수 있습니다. 생성 된 어셈블 코드를 비교할 수 있습니다. – user1641854
좋습니다. 윌 당신이 알려 드리겠습니다. –
멀티 어레이는 속도가 필요할 때 힙에서 할당 할 때 사용하는 것은 좋지 않은 생각입니다. – user1095108