x86에서 "비 시간적"메모리 액세스의 의미는 무엇입니까?


123

이것은 다소 낮은 수준의 질문입니다. x86 어셈블리에는 두 가지 SSE 명령어가 있습니다.

MOVDQA xmmi, m128

MOVNTDQA xmmi, m128

IA-32 Software Developer 's Manual에 따르면 MOVNTDQA 의 NTNon-Temporal을 의미하며 , 그렇지 않으면 MOVDQA와 동일합니다.

제 질문은 비 시간적 의미가 무엇입니까?


6
SSE4.1 MOVNTDQA xmmi, m128은 NT로드이고 다른 모든 NT 명령어는 prefetchnta. 여기서 받아 들여지는 대답은 가게에 대해서만 이야기하는 것 같습니다. 이것이 제가 NT로드에 대해 알아낼 수 있었던 것 입니다. TL : DR : CPU는 캐시 오염을 최소화하기 위해 NT 힌트로 유용한 작업을 수행하지만 "일반"WB 메모리의 강력하게 정렬 된 의미를 무시하지 않으므로 캐시를 사용해야합니다.
Peter Cordes

5
업데이트 : NT 로드 는 대부분의 CPU (예 : Intel SnB 제품군)에서 UCSW 메모리 영역을 제외하고는 유용한 작업을 수행하지 않을 수 있습니다. 하지만 NT / 스트리밍 스토어는 확실히 일반 메모리에서 작동합니다.
Peter Cordes

4
@Peter : USWC 메모리 말씀 이시죠? UCSW 또는 USWC 메모리에 대해 들어 본 적이 없습니다. 잘못된 글자가 :-) 도움이 아니 었 인터넷 검색
앤드류 베인 브릿지

4
@AndrewBainbridge : 예, WC 메모리 유형 속성입니다. 캐시 할 수없는 투기 적 쓰기 결합. UnCacheable을 대문자로 쓰고 4 자 길이로되어 있다는 것을 기억하고있는 것 같습니다. : P
Peter Cordes 2019

답변:


147

비 시간적 SSE 명령어 (MOVNTI, MOVNTQ 등)는 일반적인 캐시 일관성 규칙을 따르지 않습니다. 따라서 다른 프로세서가 적시에 결과를 볼 수 있도록 비 시간 저장 뒤에 SFENCE 명령이 와야합니다.

데이터가 생성되고 (즉시) 다시 사용되지 않는 경우 메모리 저장소 작업이 먼저 전체 캐시 라인을 읽은 다음 캐시 된 데이터를 수정한다는 사실은 성능에 해를 끼칩니다. 이 작업은 곧 사용되지 않을 데이터를 위해 다시 필요할 수있는 캐시에서 데이터를 밀어냅니다. 이것은 채워지고 나중에 사용되는 행렬과 같은 큰 데이터 구조의 경우 특히 그렇습니다. 행렬의 마지막 요소가 채워지기 전에 순전히 크기가 첫 번째 요소를 제거하여 쓰기 캐싱을 비효율적으로 만듭니다.

이와 유사한 상황에서 프로세서는 비 시간적 쓰기 작업을 지원합니다. 이 컨텍스트에서 비 시간적이란 데이터가 곧 재사용되지 않을 것이므로 캐시 할 이유가 없음을 의미합니다. 이러한 비 시간적 쓰기 작업은 캐시 라인을 읽은 다음 수정하지 않습니다. 대신 새 콘텐츠가 메모리에 직접 기록됩니다.

출처 : http://lwn.net/Articles/255364/


15
좋은 대답입니다. NT 명령어를 사용하는 프로세서 종류에서 비 시간적 명령어 (즉, 일반 명령어)를 사용하더라도 라인 캐시는 "읽고 수정"되지 않는다는 점을 지적하고 싶습니다. 캐시에없는 라인에 쓰는 일반 명령어의 경우 라인은 캐시에 예약되고 마스크는 라인의 어떤 부분이 최신인지 나타냅니다. 이 웹 페이지는 "no stall on store"라고 부릅니다 : ptlsim.org/Documentation/html/node30.html . 더 정확한 참조를 찾을 수 없었고, 프로세서 시뮬레이터를 구현하는 일을하는 사람들 에게서만 들었습니다.
Pascal Cuoq 2010 년

2
실제로 ptlsim.org 는주기가 정확한 프로세서 시뮬레이터에 대한 웹 사이트입니다. "no stall on store"에 대해 저에게 말한 사람들이하는 것과 똑같은 종류입니다. 나는 그들이이
Pascal Cuoq

1
여기에있는 답변과 의견에서 stackoverflow.com/questions/44864033/…SFENCE 필요하지 않은 것 같습니다 . 적어도 같은 스레드에서. 당신도 볼 수 있습니까?
Serge Rogatch

1
@SergeRogatch 그것은 당신이 말하는 시나리오에 따라 다르지만 sfenceNT 상점에 필요한 시나리오 가 있지만 일반 상점에만 필요한 것은 아닙니다. NT 상점은 다른 스레드 에서 볼 수 있듯이 다른 상점과 관련하여 주문되지 않습니다 sfence. 그러나 저장을 수행 한 동일한 스레드에서 읽는 경우에는 필요하지 않습니다 sfence. 주어진 스레드는 NT 저장소인지 여부에 관계없이 항상 프로그램 순서대로 자체 저장소를 볼 수 있습니다.
BeeOnRope

40

Espo는 목표물에 거의 맞았습니다. 2 센트를 더하고 싶었습니다.

"비 시간적"문구는 시간적 지역성이 부족함을 의미합니다. 캐시는 공간적 및 시간적 두 가지 종류의 지역성을 이용하며 비 시간적 명령어를 사용하여 가까운 장래에 데이터 항목이 사용될 것으로 예상하지 않는다는 신호를 프로세서에 전달합니다.

캐시 제어 명령을 사용하는 수동 코딩 어셈블리에 대해 약간 회의적입니다. 내 경험상 이러한 것들은 효과적인 성능 향상보다 더 많은 사악한 버그로 이어집니다.


"캐시 제어 명령을 사용하는 직접 코딩 된 어셈블리"에 대한 질문 JavaVM과 같은 것에 대해 "수작업으로 코딩"했다고 명시 적으로 말한 것을 알고 있습니다. 더 나은 사용 사례입니까? JavaVM / Compiler는 프로그램의 정적 및 동적 동작을 분석하고 이러한 비 시간적 명령을 사용합니다.
Pat

4
문제 도메인, 알고리즘 또는 애플리케이션의 알려진 지역 속성 (또는 그 결여)을 악용하는 것을 피해서는 안됩니다. 캐시 오염을 피하는 것은 실제로 매우 매력적이고 효과적인 최적화 작업입니다. 또한 왜 조립에 대한 혐오감이 있습니까? 컴파일러가 가능하게 활용할 수 없습니다 가능 이익의 기회 방대한 양의가있다
awdz9nld

5
지식이 풍부한 저수준 프로그래머가 작은 커널의 컴파일러보다 성능이 뛰어날 수 있다는 것은 확실히 사실입니다. 이것은 논문과 블로그 게시물을 게시하는 데 유용하며 두 가지를 모두 수행했습니다. 또한 훌륭한 교훈적인 도구이며 "정말"이 어떻게 진행되고 있는지 이해하는 데 도움이됩니다. 제 경험으로는 실제로 많은 프로그래머가 작업하는 실제 시스템이 있고 정확성과 유지 관리 성이 중요한 경우 저수준 코딩의 이점은 거의 항상 위험보다 큽니다.
Pramod

4
@Pramod이 쉽게 일반적으로 최적화 일반화된다과 같은 인수 정말 토론의 범위에 - 트레이드 오프가 이미 고려 된 또는 그렇지 않으면 우리는 이미 비 시간적 지침에 대해 이야기하고 있다는 사실 주어진 관련이없는 것으로 간주하고 명확하게
awdz9nld

7

인텔 ® 64 및 IA-32 아키텍처 소프트웨어 개발자 매뉴얼, 볼륨 1 : 기본 아키텍처, "인텔 SSE (Streaming SIMD Extensions) 프로그래밍"장에 따르면 :

임시 데이터와 비 임시 데이터 캐싱

프로그램에서 참조하는 데이터는 일시적 (데이터가 다시 사용됨) 또는 비 시간적 (데이터가 한 번 참조되고 곧 다시 사용되지 않음) 일 수 있습니다. 예를 들어, 프로그램 코드는 일반적으로 시간적이지만 3D 그래픽 애플리케이션의 표시 목록과 같은 멀티미디어 데이터는 종종 비 시간적입니다. 프로세서의 캐시를 효율적으로 사용하려면 일반적으로 비 시간 데이터를 캐시하지 않고 임시 데이터를 캐시하는 것이 바람직합니다. 비 시간적 데이터로 프로세서의 캐시를 오버로드하는 것을 "캐시 오염"이라고도합니다. SSE 및 SSE2 캐시 가능성 제어 명령을 사용하면 프로그램이 캐시 오염을 최소화하는 방식으로 비 시간적 데이터를 메모리에 쓸 수 있습니다.

비 시간적로드 및 저장 지침에 대한 설명입니다. 출처 : Intel 64 및 IA-32 아키텍처 소프트웨어 개발자 매뉴얼, 볼륨 2 : 명령어 세트 참조

LOAD (MOVNTDQA-Double Quadword Non-Temporal Aligned Hint로드)

메모리 소스가 WC (쓰기 결합) 메모리 유형 인 경우 비 시간적 힌트를 사용하여 소스 피연산자 (두 번째 피연산자)에서 대상 피연산자 (첫 번째 피연산자)로 이중 쿼드 워드를로드합니다. [...]

[...] 프로세서는 데이터를 캐시 계층으로 읽지 않으며 해당 캐시 라인을 메모리에서 캐시 계층으로 가져 오지 않습니다.

Peter Cordes가 언급했듯이 NT 힌트가 무시되고 (아마도 NT 인식 HW 프리 페 처가 없기 때문에) 전체적으로 강력하게 정렬 된로드 의미 체계가 적용되기 때문에 현재 프로세서의 일반 WB (후기 입) 메모리에서는 유용하지 않습니다. . prefetchntaWB 메모리에서 오염을 줄이는 부하로 사용할 수 있습니다.

STORE (MOVNTDQ-비 시간적 힌트를 사용하여 압축 된 정수 저장)

메모리에 쓰는 동안 데이터 캐싱을 방지하기 위해 비 시간적 힌트를 사용하여 소스 피연산자 (두 번째 피연산자)의 압축 된 정수를 대상 피연산자 (첫 번째 피연산자)로 이동합니다.

[...] 프로세서는 데이터를 캐시 계층 구조에 쓰거나 메모리에서 캐시 계층 구조로 해당 캐시 라인을 가져 오지 않습니다.

캐시 쓰기 정책 및 성능에 정의 된 용어를 사용하면 쓰기 처리 (쓰기 할당 없음, 쓰기시 가져 오기 없음)로 간주 할 수 있습니다.

마지막으로, 비 일시적 저장에 대한 John McAlpin의 메모 를 검토하는 것도 흥미로울 수 있습니다 .


3
SSE4.1 MOVNTDQA은 비디오 RAM과 같은 WC (캐시 할 수없는 쓰기 결합) 메모리 영역에서만 특별한 작업을 수행합니다. 현재 HW의 일반 WB (후기 입) 메모리에서는 전혀 유용하지 않으며 NT 힌트는 무시되고 전체적으로 강력하게 정렬 된로드 의미가 적용됩니다. prefetchnta그러나 WB 메모리 의 오염 감소 부하 로 유용 할 수 있습니다 . 현재 x86 아키텍처는 비 시간적로드 ( "일반"메모리에서)를 지원합니까? .
Peter Cordes 2018

2
맞습니다. NT 저장소는 WB 메모리에서 잘 작동하고 약하게 정렬되어 있으며 일반적으로 큰 메모리 영역 을 작성 하는 데 좋은 선택입니다 . 그러나 NT로드는 그렇지 않습니다. 종이에 x86 매뉴얼은 NT 힌트가 WB 메모리의로드에 대해 무언가를 할 수 있도록 허용하지만 현재 CPU에서는 아무것도 하지 않습니다 . (아마도 NT 인식 HW 프리 페 처가 없기 때문일 것입니다.)
Peter Cordes

나는 그 관련 정보를 답변에 추가했습니다. 대단히 감사합니다.
chus

1
@LewisKelsey : NT 저장소 는 메모리 유형을 재정의합니다. 이것이 WB 메모리에서 약하게 정렬 될 수있는 이유입니다. 주요 효과는 RFO를 피하는 것입니다 (분명히 그들은 mem에 도달하면 다른 더티 라인을 지우는 무효화를 보냅니다). 또한 비 순차적으로 표시 될 수 있으므로 이전 캐시 미스 (일반) 스토어 커밋 후 또는 이전 캐시 미스 로드 가 데이터를 가져올 때까지 기다릴 필요가 없습니다 . 즉, 다중 프로세서 시스템에서 각 코어 외부의 메모리가 항상 개념적으로 평탄한 / 균일 / 동 기적입니까? .
Peter Cordes 2019 년

1
@LewisKelsey : 메모리 주문 시스템 지우기는 필요한 경우 조기에 수행해서는 안되는 UC 저장소 이후의로드를 중단 할 수 있습니다. 그 외에는 스토어가 비 순차적 백엔드에서 은퇴 할 때까지 커밋 순서가 작동하지 않습니다. 이는 store-address uop가 실행될 때까지 발생하지 않으며,이 시점에서 주소의 메모리 유형을 확인할 수 있습니다. 상점 주소 uop는 실행될 때 TLB를 확인합니다. 이것이 CPU가 폐기되기 전에 결함이있는 저장소를 감지하는 방법입니다. SB 항목이 L1d에 커밋 할 준비가 될 때까지 기다릴 수 없습니다. 그 시점에서 실행이 지나갔습니다.
Peter Cordes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.