将AoS转换为SoA时处理组合爆炸

问题描述 投票:0回答:1

假设我想将结构数组转换为具有运行时参数的数组结构,该参数指示应转换源结构的哪些成员。例如:

struct SourceElement {
  string member1;
  float member2;
  int member3;
  //More members...
};
auto source_elements = ...; //A forward-iterable range of SourceElement objects

vector<string> members1;
vector<float> members2;
vector<int> members3;

for(auto& source_element : source_elements) {
  if(member1_required) {
    members1.push_back(source_element.member1);
  }
  if(member2_required) {
    members2.push_back(source_element.member2);
  }
  if(member3_required) {
    members3.push_back(source_element.member3);
  }
  //...and so on...
}
//Some of the vectors might be empty, which I am fine with

我想摆脱循环中的条件,希望无条件代码运行得更快。我知道的典型方法是简单地将条件移出循环,如果它只是一个条件,则效果很好,但是对于多个条件,这会导致组合爆炸-对于N成员,我必须写[C0 ]不同的环体。添加新成员还需要编写大量代码。这是一个看起来如何的示例:

2^N

解决此类问题的好方法是什么?理想的解决方案应具有以下属性:

  • 生成的代码应尽可能接近手动解决方案(每个组合一个for循环)
  • 添加新成员应该花费很少的精力
  • 解构源元素应允许进行数据转换(例如if(member1_required && !member2_required && !member3_required) { for(auto& source_element : source_elements) { members1.push_back(source_element.member1); } } else if(member1_required && member2_required && !member3_required) { for(auto& source_element : source_elements) { members1.push_back(source_element.member1); members2.push_back(source_element.member2); } } //... and so on )。一个简单的例子:SourceElement有一个members1.push_back(my_conversion(source_element.member1))成员,但是我只想存储double数据
  • 源数据可能来自前向迭代器,因此不能假定所有数据都直接存储在内存中
c++ performance
1个回答
0
投票

您可以使用模板,示例(未经测试):

float

但是,我不确定这是否会对效果产生可观的影响。所有现代CPU都进行分支预测。这些条件在您迭代时不会改变。在第一次循环迭代之后,所有这些分支将以100%的准确性进行预测。

© www.soinside.com 2019 - 2024. All rights reserved.