2013-04-15 3 views
3

Я разработал генератор Мандельброта для Windows, который я только что переработал для использования SSE Intrinsics. Чтобы обнаружить конец итераций, в обычной арифметике я делаю больше, чем сравнивать и вырываться. Выполняя это в SSE, я могу сравнить весь вектор с помощью _mm_cmpgt_pd/_mm_cmpgt_ps, однако это напишет новый 128-битный вектор со всеми 1s для случая, о котором я забочусь.SSE Intrinsics: Самый быстрый способ проверить все 0 или 1?

Мой вопрос в том, есть ли более эффективный способ обнаружения для всех 1-х, а не для проверки 2-х упакованных 64 INTs? Или, если более эффективно обнаруживать для всех 0, то я мог бы сравнивать меньше. Вот то, что я в настоящее время:

_m128d CompareResult = Magnitude > EarlyOut; 
const __m128i Tmp = *reinterpret_cast< __m128i* >(&CompareResult); 
if (Tmp.m128i_u64[ 0 ] == Tmp.m128i_u64[ 1 ] == -1) 
{ 
    break; 
} 

Поэтому я хочу, чтобы найти лучший способ, потому что я не люблю актеров, но и потому, что в соответствии с Vtune более чем на 30% моего времени итерации проводится в этом Последняя линия. Я знаю, что многое будет в самой ветке, но я предполагаю, что смогу уменьшить это с лучшим обнаружением 0 или 1.

Благодаря

+0

См: http://stackoverflow.com/questions/10175711/check-xmm-register -for-all-zeroes –

ответ

7

Предполагая, что вы проверяете результат сравнения, то вы можете просто извлечь биты MS каждого байта в виде 16-разрядного междунар и проверить это, например,

int mask = _mm_movemask_epi8((__m128i)CompareResult); 
if (mask == 0xffff) 
{ 
    // compare results are all "true" 
} 

Обратите внимание, что это один из примеров более общей методики для SIMD предикаты в SSE, т.е.

mask == 0xffff // all "true" 
mask == 0x0000 // all "false" 
mask != 0xffff // any "false" 
mask != 0x0000 // any "true" 
+1

Я думаю, что это наиболее эффективное решение. Может потребоваться 0xFFFF вместо 0xFF при использовании 128-битных данных. – ScottD

+0

Спасибо за ответ. Я вытащил это, и это было очень немного медленнее, чем моя оригинальная версия. Кроме того, мне все еще нужен уродливый бросок, так как мой тип переменной SSE - __m128d, хотя я сделал его ссылкой на константу, которая также сэкономила некоторое время. – allanmb

+0

Обратите внимание, что изображение производительности может варьироваться в зависимости от разных процессоров и разных компиляторов, т. Е. Вы можете получить выигрыш в некоторых случаях, но не в других, поэтому, если это код для общего распространения, вам может потребоваться сравнить с другими CPU, если вы можете , –

Смежные вопросы