фон: Так что я работаю на Raytracer .. для моей конструкции схемы пространственного разделения, я изначально имел некоторый код, как это:Загадочного указатель связанной многопоточности замедление
if (msize <= 2) { // create a leaf node
Model **models = new Model*[msize];
for (uint i=0; i<msize; ++i)
models[i] = &mlist[i];
*arrayPtr = Node(models, msize); // class Node contains a copy of models
... increment arrayPtr ...
return;
}
В принципе, после этого пространственного дерево разбиения построено, лучи пересекают дерево, ища модели, которые все хранятся в одном большом массиве. Листовые узлы содержат указатели на массив указателей моделей.
Тогда я понял, что эй, нет причин для меня добавить этот дополнительный уровень косвенности; если я правильно устрою свои модели, я могу получить узлы листа, чтобы указать на большой массив моделей. Модели, прилегающие друг к другу в большом массиве, будут принадлежать данному листовому узлу, поэтому листья будут содержать указатели на модели. Поэтому я сделал это и протестировал его, оставив все остальное неизменным.
Теперь можно было бы подумать, что это, очевидно, ускорит программу. Ну, это ускоряет однопоточную версию (примерно на 10%), но она замедляет многопоточность (примерно на 15%! Это довольно важно, если вы делаете большую оптимизацию.) Я вполне уверен потеря на том, как справиться с этим - я думал, что косвенность была плохая, я думал, что сокращение использования памяти было хорошим, особенно для многопоточности .. нет никакой записи для листового узла или Модели, все записи выполняются в отдельной структуре данных ,
Любые указатели/рекомендации по анализу проблемы были бы замечательными.
Некоторые статистические данные: cachegrind сообщает мне, что для подхода с двойной привязкой имеется меньше ошибок ref/cache misss, но больше не хватает данных refs/cache. Разница не такая большая, хотя для обоих.
Edit: В соответствии с просьбой, структура данных, что меня интересует:
class Node {
ushort type;
union {
ushort axisID;
ushort childrenSize;
};
union {
Model **models;
Node *rightChild;
};
float leftPlane, rightPlane;
... public methods and stuff ...
}
Я в принципе изменить Model **models
к Model *models
, а затем я получаю скорость купания. Класс Model
сам содержит указатель на два абстрактных класса, Shape
и Material
. Все классы, упомянутые здесь, выделены блоком, за исключением Material
, так как в данный момент я просто использую один.
Можете ли вы опубликовать две версии структур данных, которые вы сравниваете? –
Проблемы с псевдонимом, возможно? Это почти всегда моя первая мысль, когда я вижу объединение в C/C++. Какая конкретная функция делает профайлер более медленным? Вы посмотрели на разборку, чтобы увидеть, существуют ли какие-либо различия? – jalf
Как вы делитесь данными между потоками? – Malkocoglu