2010-03-18 6 views
4

가끔씩 많은 양의 메모리를 복제해야하는 실시간 시스템을 설계하고 있습니다. 메모리는 작은 영역으로 구성되어 있으므로 복사 성능이 관련 구성 요소 (CPU, RAM, MB)가 수행 할 수있는 최대 대역폭에 상당히 근접 할 것으로 예상됩니다. 이것은 내가 현대 상품 기계가 소집 할 수있는 원시 메모리 대역폭의 종류를 궁금해하게했다.현대 기계의 메모리 대역폭 성능

하나의 스레드를 memcpy()에 사용하면 내 에이징 Core2Duo에서 1.5GB/s를 제공합니다. (두 코어를 동시에 사용하면 memcpy()이 적어집니다.) 1.5GB는 상당한 양의 데이터이지만, m 작업은 1/50th, 즉 30MB를 의미합니다. 기본적으로, 거의 아무것도. 그리고 아마도 최악의 경우, 여러 개의 코어를 추가 할 때 필 요한 복제 단계의 성능을 향상시키지 않고 훨씬 많은 데이터를 처리 할 수 ​​있습니다.

하지만 저가형 Core2Due는 요즘 엄청난 인기를 얻지 못합니다. 실제 벤치 마크와 같은 정보가있는 사이트가 현재 및 미래의 하드웨어의 원시 메모리 대역폭에 있습니까?

또한 많은 양의 데이터를 메모리에 복제하려면 단축키가 있습니까? 아니면 memcpy()만큼 좋을까요?

짧은 시간에 할 일없이 가능한 한 많은 메모리를 복제 할 수있는 코어가 제공된다면 무엇을 할 수 있을까요?

편집 : 아직 원시 메모리 복사 성능에 대한 좋은 정보를 찾고 있습니다. 방금 memcpy() 벤치 마크를 실행했습니다. 동일한 기계 및 설정은 이제 2.5GB/s를 제공합니다 ...

+1

첫 번째 질문은 "왜"라고 생각합니다. 특히, 달성해야 할 많은 양의 메모리를 복제하는 것은 무엇입니까? 복사 할 때 메모리를 수정하지 않으므로 포인터를 전달하면 대역폭을 전혀 사용하지 않고 동일한 작업을 수행해야합니다. –

+0

"왜"를 기다리고있었습니다. 이 경우에는 두 가지 상태가 필요하기 때문에 : 원격 백업으로 천천히 보내야 할 사본과 원본을 수정 유지해야하기 때문입니다. – porgarmingduod

답변

2

Nehalem과 같은 최신 CPU 및 Opteron 이후 AMD에서 메모리는 하나의 CPU에 대해 "로컬"이며, 단일 CPU가 여러 개의 코어. 즉, 코어가 CPU에 연결된 로컬 메모리에 액세스하는 데 일정 시간이 걸리고 코어가 원격 메모리에 액세스하는 데 더 많은 시간이 소요됩니다. 원격 메모리는 다른 CPU에 대해 로컬 인 메모리입니다. 이를 비 균일 메모리 액세스 또는 NUMA라고합니다. 최상의 memcpy 성능을 얻으려면 BIOS를 NUMA 모드로 설정하고 스레드를 코어에 고정하고 항상 로컬 메모리에 액세스하려고합니다. NUMA on wikipedia에 대해 자세히 알아보십시오.

최근 CPU 및 칩셋에 대한 memcpy 성능에 대한 사이트 또는 최근 논문을 알 수 없습니다. 아마 최선의 방법은 직접 테스트하는 것입니다.

성능은 memcpy()이고 구현에 따라 다양한 변형이 있습니다. Intel C 라이브러리 (또는 아마도 컴파일러 자체)는 Visual Studio 2005에서 제공되는 것보다 훨씬 빠른 memcpy()을 가지고 있습니다. 최소한 인텔 컴퓨터에서.

당신이 할 수있는 최선의 메모리 카피는 데이터 정렬, 벡터 명령어 사용 가능 여부 및 페이지 크기 등에 달려 있습니다. 좋은 구현은 놀라 울 정도로 복잡합니다. 직접 작성하기 전에 최대한 많은 구현을 테스트하십시오. 정렬 및 크기와 같은 복사본에 대한 자세한 내용을 알고있는 경우 은 Intel의 memcpy()보다 빠른 것을 구현할 수 있습니다. 자세한 내용을 보려면 Intel 및 AMD 최적화 안내서 또는 Agner Fog's software optimization pages으로 시작하십시오.

+0

일반적으로 유익한 내용이지만이 대답의 일부 측면은 내가 언급 한 구체적인 내용을 놓친 것 같습니다. 예를 들어 나는 분명히 내가 많은 양의 메모리를 복사한다고 말하고있다. 이것은 캐시가별로 중요하지 않다는 것을 의미합니다.이 경우의 메모리 병목 현상은 기본적으로 RAM에서 비롯된 것이며, 다시 RAM으로 돌아갑니다. "로컬"메모에서 메모를 읽는 방법은 캐시에 대해 이야기하는 것입니다. 또는 코어에 "로컬"인 메인 RAM 부분이 있습니까? 나는 그런 것을 듣지 않았지만 나를 고쳐 주셔도 좋습니다. – porgarmingduod

+0

아니요, 로컬 메모리에 관해 말할 때 캐시를 참조하지 않았습니다. NUMA 시스템에서는 서로 다른 RAM 뱅크가 물리적으로 서로 다른 코어 또는 다른 CPU 소켓에 연결됩니다. 2 소켓 시스템에서는 RAM의 절반이 물리적으로 첫 번째 소켓에 연결되고 절반은 두 번째 소켓에 연결됩니다. 두 번째 소켓의 코어가 첫 번째 소켓에 연결된 메모리에 액세스해야하는 경우 데이터는 첫 번째 소켓을 먼저 통과하는 더 긴 경로를 따라야합니다. 필기장에 대한 링크를 추가하겠습니다. – mch

+1

@mch 아마도 CPU 소켓이 아닌 코어를 참조 할 때 대답을 편집해야합니다. –

1

나는 당신이 문제를 잘못된 방향으로 접근하고 있다고 생각합니다. 목표는 실시간 성능을 저하시키지 않고 데이터의 일관된 스냅 샷을 내보내는 것입니다. 하드웨어를 사용하지 말고 알고리즘을 사용하십시오.

원하는 것은 데이터 상단에 저널링 시스템을 정의하는 것입니다.메모리 내 전송을 시작하면 작동하는 원본과 데이터를 수정하는 것으로 생각되지만 실제로는 저널에 쓰고있는 원본과 이전의 (저널되지 않은) 데이터를 저널에 복사하는 새 스레드라는 두 가지 스레드가 있습니다. 별도의 지점 그래서 천천히 그것을 밖으로 쓸 수 있습니다.

새 스레드가 완료되면 저널이 비어있을 때까지 저널과 데이터 세트를 병합하도록 설정합니다. 완료되면 이전 스레드는 저널 수정 버전을 통해 읽거나 쓰는 대신 데이터와 직접 상호 작용할 수 있습니다.

마지막으로 새 스레드가 복사 된 데이터로 이동하여 천천히 원격 소스로 전달할 수 있습니다.

이와 같은 시스템을 설정하면 저널이 너무 꽉 차기 전에 메모리 내 복사본을 완료 할 수 있다면 실행중인 시스템에서 임의의 많은 양의 데이터를 즉시 스냅 샷으로 얻을 수 있습니다 시간 시스템은 처리 요구를 따라갈 수 없다.

+1

사실 처음에는 내 질문에 이르게하는 문제를 해결하는 알고리즘을 가지고 있습니다. 그러나 내 질문은 메모리 복사의 실제 성능에 관한 것이지 메모리 이동을 피할 수있는 다양한 방법이 아닙니다. – porgarmingduod