Алгоритм, с которым я работаю, тратит огромную часть времени на сравнение одного массива с строкой матрицы. Если любой i-й элемент один и тот же, алгоритм вызывает процедуру A, если ни один элемент не равен, вместо этого вызывается процедура B. Например:
[1, 4, 10, 3, 5]
и [5, 3, 0, 3, 0]
вызывает A()
, потому что для 4-й позиции значение равно 3 в обоих массивах.
[1, 4, 10, 3, 5]
и [5, 3, 0, 1, 0]
вызывает B()
, потому что для той же позиции значения никогда не совпадают.
Заметим, что (1) массивы и строки матрицы всегда имеют одинаковый размер N, и (2) алгоритм вызывает A()
, когда соответствует хотя бы одно значение.
Самый простой, но очень наивный способ сделать это в C:
for(int i=0; i<N; i++)
if( A[i] == B[i] ){
flag = 1;
break;
}
Это все еще очень неэффективно. В худшем случае у меня будет N сравнений. Реальная проблема здесь заключается в том, что алгоритм выполняет триллионы этих сравнений.
N (размер массива/строки в матрице) варьируется от 100 до 1000. Я бы хотел ускорить эту процедуру. Я посмотрел на векторию, и я обнаружил, что могу использовать cmpeq_pd
. Однако векторизация будет по-прежнему ограничена, потому что все мои записи longs
. Есть ли кто-нибудь с идеей? Могу ли я применять маски и т.д., Возможно?
Дополнительная информация/контекст:
- Это итеративный алгоритм. На каждой итерации я увеличиваю матрицу в одной строке и проверю всю матрицу несколько раз. Я мог бы также обновить пару строк.
- Вероятность совпадения не зависит от позиции.
- Я готов иметь ложные срабатывания и негативы, чтобы значительно ускорить эту процедуру.
- Если есть совпадение, позиция, в которой проверяется совпадение, имеет значение не (мне просто нужно знать, есть ли подходящая позиция).
- Самое большое количество (около 70%) сравнений не приводит к совпадению.
- Параллелизация выполняется на другом уровне, т.е. это ядро нельзя распараллелить.