문제

으로 제목에서 알 수 있듯이,문제가 있었 프로그램을 내는 데 사용되는 std::list 로 스택과 또한 반복을 통해 모든 요소의 목록에 있습니다.프로그램을 복용하는 방법이 너무 긴 경우 목록되었습니다.

누군가를위한 좋은 설명이 이?그것은 몇 가지 스택/캐시 동작?

(문제를 해결을 변경하여 나열하는 std::벡터와 std::야 하는(는 놀라운 데이터 구조 방법에 의해)및 모든 것 갑자기 그렇게 훨씬 더 빠르게)

편집:난 바보가 아니고 나가지 않 요소에 대한 액세스의 목록입니다.이어진 목록되었 추가/제거하는 요소를 끝에/작을 반복하고 모든 요소의 목록에 있습니다.그리고 나는 항상 사용되는 반복기를 통해 반복하는 목록에 있습니다.

도움이 되었습니까?

해결책

목록 끔찍한(는 존재하지 않다)캐시지입니다.모든 노드가 새로운 메모리 할당은 될 수 있습니다 어디서나.그래서 시간을 따르는 포인터부터 다음 노드,이동할 새로운 서로 관련이 없는 장소에서 메모리입니다.그리고 예,아파 성과 꽤 있습니다.캐시 놓칠 수 있습니다 두 가지 주문의 크기보다 느리게 캐시했다.에서 벡터나야 하는,거의 모든 액세스할 수 캐시했다.벡터는 하나의 연속적인 메모리 블록,그렇게 반복은 빨리 당신이 얻을 수 있습니다.A 야 하는 여러 개의 작은 블록의 메모리,그래서 그것을 소개합니다 가끔 캐시 놓치지만,그들은 여전히 드물고 반복 여전히 매우 빠른 것으로 당신이 있어요 주로 캐시니다.

목록될 것이 거의 모든 캐시를 벗어났습니다.과 성능을 빨아 것입니다.

실제로 연결 목록은 거의 올바른 선택 성능에서의 관점입니다.

편집:주석으로,지적 또 다른 문제는 목록은 데이터가 종속성입니다.현대 CPU 를 좋아하는 겹치는 작업입니다.하지만 그것을 할 수 없는 경우 다음 명령에 따라 달라집의 결과이다.

당신은 반복하는 벡터,즉,아무 문제 없습니다.계산할 수 있습니다 다음 주소에서 읽을 비행하지 않고,확인 메모리에 있습니다.를 읽는 경우에 주소 x 지금은,그 다음 요소에 위치하게 될 주소 x + sizeof(T) T 는 요소의 유형입니다.그래서 아무 의존성이며,CPU 시작할 수 있는 선적은 다음 요소,또는 후에 즉시 그것을하는 동안,여전히 이전에 처리하는 요소입니다.는 방법으로 데이터에 대한 준비가 될 것입니다 우리가 우리가 그것을 필요로 할 때,이는 또한 마스크의 비용 데이터에 액세스 RAM.

목록에서,우리가 필요한을 따르는 포인터 에서 노드 i 노드 i+1, 까지 i+1 로드 된,우리는 알지도 못하는 i+2.우리는 데이터는 종속성,그래서 CPU 강제 노드를 읽을 한 번에 하나씩,그리고 그것을 시작할 수 없음을 읽는 미래 앞서 노드의 시간,그렇지 않기 때문에 아직 어디에 있는지 알고 있다.

목록을 경우에 없었던 모든 캐시 누락,이하지 않았을 것이다 큰 문제이지만,때문에 우리는 점점 많이 캐시를 벗어났고,이러한 지연은 비용이 많이 듭니다.

다른 팁

그것은으로 인해 대량의 캐시를 벗어났을 때 사용하여 목록입니다.과 벡터의 주변 요소에 저장된 프로세서 캐시입니다.

보 다음 직접 스레드.

캐시 문제점:모든 데이터는 벡터에 저장된 연속적인 덩어리,그리고 각 목록 요소 할당된 별도로 발생할 수 있습니다장에서 매우 임의의 장소의 기억에 지도하는,더 캐시를 벗어났습니다.그러나 내가 발생하는 문제 중 하나에 설명된 다른 답변이 있습니다.

간단한 대답이기 때문에 반복하는 벡터지 않을 반복하고 모두에서,그것은 단지 시작에 기초의 배열을 읽고 요소 중 하나입니다.

나는 이런 표시된 C++,C,그 이후 그들은 같은 일에 그것의 가치가 요소를 추가할 수 있습니다 처음과 끝의 배열을 할당하여 임의로 큰 및 realloc()ing 및 memmove()ing2 동반자 배열한 경우 밖으로 실행합니다.매우 빠르다.

트릭을 추가하는 요소를 시작 부분의 배열은 바이어스 논리적 시작의 배열을 진행하여 포인터 배열로 시작한 다음 백업을 추가하는 경우 요소가 앞으로 내리게 되어 있습니다.(또한 방법으로 스택 구현되)

에 정확히 동일한 방식으로,C 을 만들 수 있습을 지원하는 부정적인 첨자.

C++을 위해 모든 작업을 수행하고 당신과 벡터 STL 등,하지만 여전히 가치가있을 기억에 무슨 일이에서 다룹니다.

[편집:나는 수정되었습니다.std::목록에 없는 운전자[].죄송합니다.]

그것은 말하기 어렵에서 설명하지만 생각을 했다 액세스하려고 하는 항목은 무작위로(즉,인덱스):

for(int i = 0; i < mylist.size(); ++i) { ... mylist[i] ... }

를 사용하는 대신 반복기:

for(list::iterator i = mylist.begin(); i != mylist.end(); ++i) { ... (*i) ... }

모두"vector"&"야 하는"좋은 랜덤 액세스,그래서 어느 것이 적절하게 수행하는 유형---O(1)두 경우 모두에서.하지만"list"좋지 않은 랜덤 액세스입니다.액세스 목록을 인덱스는 것을 O(n^2)시간,대 O(1)사용하는 경우 이터레이터입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top