2012-07-02 2 views
0

은 내가 스파 스 행렬을 나타 내기 위해이 구조체를 사용하려는구조 :: device_vector

struct Point 
{ 
int x; 
int y; 
float val; 
} 

같은 구조를 가지고 (나는 CUSPARSE과 ​​끝을 알고 모르지만, 난 그냥 추력을 사용하여 몇 가지 테스트를 수행 할 예정) 및 추진 알고리즘을 사용하여 작업을 수행하십시오.

내가 CUDA 프로그래밍 튜토리얼에서 공부 한 내용은 항상 메모리 병합을 위해 구조체 배열보다는 배열 구조체를 사용하는 것이 좋습니다.

만약 위의 구조체를 사용하여 device_vector 안에 0이 아닌 값 (수백만 단위로)을 저장하면이 장치 _ 벡터는 추력 알고리즘을 처리하는 동안 GPU 내부에서 정렬되지 않은 메모리 액세스를 사용합니까?

이 device_vector 내의 불규칙한 스트라이드에 액세스하고 복수 함수 객체를 전달하여 알고리즘 연산을 수행해야 할 수도 있기 때문에이 질문을드립니다.

배열의 구조체에서 작동하는 사용자 정의 커널만큼 효율적입니까?

감사합니다.

답변

4

NVIDIA CUDA 디바이스는 통합 메모리 액세스 패턴을 효율적으로 가정하여 4, 8 및 16 바이트 구조에 효율적으로 액세스 할 수 있습니다. 이를 위해 CUDA 헤더는 사용할 수있는 구조체 int2, int4, float2, float4 등을 정의합니다. 그들은 효율적으로 정렬 그래서 대신 사용자 정의 포인트 구조체를 갖도록 정의되어, 나는 모든 데이터를 (예 합체) 워프에 순차적에서 스레드를

typedef int2 Point; 

모든 메모리가이 작은 구조체의 배열에 액세스

을하는 사용 및 추천 각 struct 요소에서 읽기/쓰기 스레드에 의해 사용되면 AOS 액세스 유형이 매우 효율적입니다. 사실 이와 같은 벡터 구조체를 사용하면 증가하는 메모리 트랜잭션으로 인해 스칼라 데이터 액세스보다 메모리 처리량이 높아질 수 있습니다.

추력은 특별히 AOS 데이터 인 것처럼 SOA 데이터에서의 조작의 편리 성과 (코딩) 효율성을 위해 zip_iterator을 제공합니다. 따라서 작은 구조체가 CUDA C++에서 효율적이지만 추력을 사용할 때는 transform 및 다른 추력 알고리즘을 호출하기 전에 zip_iterator을 사용하여 각각의 구조체 멤버에 대해 device_vector을 별도로 사용하도록 선택할 수 있습니다. Thrust 샘플 코드에 포함 된 예제가 있습니다.

+1

특히 커스텀 커널에 대해서는 동의 하겠지만, 추력에 대한 특별한 사용을 위해서는 단순히 3 개의 장치 벡터 (또는 좌표의 경우 벡터 쌍/튜플 또는 데이터의 경우 벡터)를 사용하는 것이 좋습니다. 더 간단하고 쉽게 작업 할 수 있습니다. – talonmies

+1

죄송합니다, 나는 추력에 관한 부분을 놓쳤습니다. 그 사건을 다루기 위해 내 대답을 편집했습니다. 대역폭에 제약이있는 경우 작은 구조체를 사용하고 추력에서 작동하도록 사용자 지정 펑터를 작성하는 것이 더 효율적일 수 있습니다. – harrism

+0

@harrism ... 내 구조체를 정의하는 동안 __align__ 연산자를 사용하여 끝내니까 고마워. 내면 밀어 넣을 때 효율적으로 사용할 수 있을까? – Recker