2017-02-17 19 views
2

Мой вопрос очень прост и, надеюсь, имеет и хороший ответ: когда у меня есть построенная матрица Eigen::MatrixXd, могу ли я использовать несколько потоков для заполнения строк в матрице при одном и том же (если я могу заверить, что строки не записываются одновременно), или я должен создавать временные объекты строк в каждом потоке, а затем копировать (тьфу ...) их в матрицу как операцию сокращения?Thread-safe writing to Eigen :: MatrixXd по строке

ответ

3

Хотя он может быть потокобезопасным с точки зрения того, что он не писал на тот же адрес из разных потоков, потому что Eigen::MatrixXd имеет большое хранилище столбцов, вы, скорее всего, будете разрушать хаос (в основном, это ложный доступ). Быстрее может создать матрицу временных строк, а затем скопировать ее на основную матрицу столбца.

В качестве альтернативы (и лучше ИМО) вы можете обрабатывать столбцы в своей существующей матрице в виде строк (убедитесь, что размеры переключаются/совпадают), а затем выполните m.transposeInPlace(). В зависимости от формы и выравнивания матрицы это может быть более эффективным, чем m = m.transpose().eval().

Также может можно использовать идентификаторы резьбы, если матрица является достаточно большой и идентификаторы равны нуль основы и последовательного (например, с OMP или подобные, не например std::thread без отслеживания различных идентификаторов самостоятельно). Для этого также требуется заполнить матрицу так, чтобы количество строк было кратно размеру строки кеша, и каждый столбец запускается в выровненном блоке памяти. Предположим, что длина кеша составляет 64 байта. Если вы обрабатываете блоки с целым числом, кратным этому, то вы можете избежать ложного обмена, так как каждый поток касается только своих «собственных» строк кеша. Если вы можете это сделать, тогда не должно быть дополнительных времен или копий/свопов.

+0

Как насчет использования Eigen :: RowXpr на Eigen :: MatrixXd - имеет ли тот же самый штраф за кеш? Я получил это для работы - прохождение Eigen :: RowXpr - но на самом деле это не казалось намного быстрее или лучше, чем просто создание временного и использование этого напрямую. – ibell

+0

«Проблема» - это базовый макет памяти и разные потоки, записывающие соседние адреса в одной и той же строке кэша, а не то, как вы пишете выражение. Вы должны опубликовать [mcve], если у вас есть более конкретный вопрос/проблема. –