【问题标题】:Optimized conversion from Milliseconds to hours:minutes:seconds:mseconds digits?从毫秒到小时:分钟:秒:毫秒数字的优化转换?
【发布时间】:2018-05-17 11:44:24
【问题描述】:

您有什么建议可以优化从毫秒 msecsOut 到 9 位别名 iX: 8H 7H 6M 5M 4S 3S 2MS 1MS 0MS 的转换,假设循环是给定的约束,模数可能不是最理想的,到目前为止我有:
(我们正在使用 systemc 编程在 XILINX 的 Spartan-3 FPGA 系列上)

int msecsOut = 1234123412;
// iX: 8H 7H 6M 5M 4S 3S 2MS 1MS 0MS
for (int i = 8; i >= 0; --i) {
    int digitOut = -1;
    if (i == 8) {
        digitOut = msecsOut / (1000 * 60 * 60 * 10);
        msecsOut = msecsOut % (1000 * 60 * 60 * 10);
    } else if (i == 7) {
        digitOut = msecsOut / (1000 * 60 * 60);
        msecsOut = msecsOut % (1000 * 60 * 60);
    }  else if (i == 6) {
        digitOut = msecsOut / (1000 * 60 * 10);
        msecsOut = msecsOut % (1000 * 60 * 10);
    }  else if (i == 5) {
        digitOut = msecsOut / (1000 * 60);
        msecsOut = msecsOut % (1000 * 60);
    }  else if (i == 4) {
        digitOut = msecsOut / (1000 * 10);
        msecsOut = msecsOut % (1000 * 10);
    }  else if (i == 3) {
        digitOut = msecsOut / (1000);
        msecsOut = msecsOut % (1000);
    }   else if (i == 2) {
        digitOut = msecsOut / (100);
        msecsOut = msecsOut % (100);
    }   else if (i == 1) {
        digitOut = msecsOut / (10);
        msecsOut = msecsOut % (10);
    }   else if (i == 0) {
        digitOut = msecsOut / (1);
    }
    cout << digitOut << " ";//debug only
}
cout<<endl;//debug only

【问题讨论】:

  • 我要做的第一件事就是摆脱分歧。我从未使用过 systemC,因此我不知道您是否可以合成 / 运算符,但我敢打赌,在门中它会非常非常昂贵。
  • @Oldfart 如果 C 编译器稍微优化一下,他们不会有任何划分:godbolt.org/g/HxUo2h
  • "假设循环是给定的约束" :(
  • 为什么“假设循环是给定的约束”?
  • a) 此代码不是 C,因此请不要标记。 b) 您正在使用loop-switch sequence here,这是一个已知的反模式。不。 c) 你甚至不需要任何 ifs...

标签: c++ performance optimization fpga


【解决方案1】:

您可能会通过使用数组摆脱测试 i(这会使您的循环无用)

int msecsOut = 1234123412;
const int factors[] = {
      1000 * 60 * 60 * 10,
      1000 * 60 * 60,
      1000 * 60 * 10,
      1000 * 60,
      1000,
      100,
      10
};
const char* symbols[] = {"H", "H", "M", "M", "S", "S", "MS", "MS"};
// iX: 8H 7H 6M 5M 4S 3S 2MS 1MS 0MS
for (int i = 0; i != sizeof(factors) / sizeof(*factors); ++i) {
    const int digitOut = msecsOut / factors[i];
    msecsOut = msecsOut % factors[i];
    std::cout << digitOut << symbols[i] << " ";
}
std::cout << msecsOut << "MS" << std::endl;

【讨论】:

  • 这对于合成来说仍然相当低效。 DIV 和 MOD 非常昂贵。有几种方法可以以区域有效的方式做到这一点: 1. 迭代减法器/加法器。但这不会很快。 2. 将 DIV 和 MOD 操作更改为 32 循环实现。但我想最大的问题是:为什么要在 FPGA 中进行用户界面转换?
  • 我希望编译器使用类似std::div 的东西通过迭代只进行一次计算。正如评论中的状态std::cout 可能是这里的瓶颈。
猜你喜欢
  • 2012-06-08
  • 2018-11-16
  • 2013-01-12
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多