2013-05-16 1 views
0

Clang имеет/C расширение C++ то, что позволяет рассматривать значение вектора, как и граждане первого класса:В Mac OS X, эффективнее ли передавать векторы по ссылке или по значению?

typedef double double4 __attribute__((ext_vector_type(4)); 
// easy assignment 
double4 a = {1, 2, 3, 4}; 
double4 b = {4, 3, 2, 1}; 
// basic operators work component-wise 
double4 c = a + b; // {5, 5, 5, 5} 
// you can even swizzle elements! 
double4 d = a.zyxw; // {3, 2, 1, 4} 

Я считаю, что эти векторы используют инструкции SIMD Базовой платформы (SSE на Intel Macs, NEON на ARM). Тем не менее, я не слишком уверен, как соглашение о вызове Mac OS имеет дело с типами векторов.

Будет ли более эффективно передавать векторы по ссылке или путем копирования? Разница может быть не огромной, но поскольку я буду проходить вокруг множества векторов, я решил, что смогу как можно скорее подобрать правильную привычку.

+0

Регистры SSE имеют ширину 128 бит, но 'double4' имеет ширину 256 бит. –

+0

@ DietrichEpp, я понимаю, что AVX принес 256-битные регистры 'ymm0'' ''ymm15' (' xmm' теперь относится к нижним 128 бит из них). – zneak

+1

AVX не включен по умолчанию. –

ответ

1

Быстрый тест показывает, что в вашем примере аргументы передаются в стек, но возвращаются в регистры xmm0 и xmm1. Это немного странно. float4 с другой стороны передаются в регистры xmm0 до xmm7, а результаты возвращаются в xmm0, как и следовало ожидать.

Apple использует Системный прикладной бинарный интерфейс. Приложение архитектуры AMD64. для Mac OS X. Если я правильно интерпретирую этот документ, все должно быть передано в регистры. Я не уверен, что делает clang здесь. Может быть, это все еще продолжается и может измениться в будущем? Если они это сделают, это может сломать вашу программу, когда вы попытаетесь смешать старое и новое поведение.

Для исполнения передающие векторы на значение с clang не являются проблемой. Если ваши функции не очень короткие, не должно быть различий. Если вы используете очень маленькие функции, вы должны попытаться убедить компилятор подключить их (например, объявив их static).

EDIT: Что касается расширений AVX: при их включении компилятор использует регистры ymm0 для ymm7 для аргументов и ymm0 для получения результатов. В этом случае double4 занимает один регистр ymm вместо пары xmm register.

+0

Как это можно вернуть в 'xmm0'? Это половина необходимой ширины. – zneak

+0

@zneak Поплавок4 имеет 128 бит и вписывается в xmm0. Параметр double4 равен 256 бит и возвращается в регистровой паре xmm0 и xmm1 (сокращенно xmm0/1). –