最有效地将编译时大小的数组的所有元素相加

2024-06-01

我正在尝试使用最少量的指令,有效地将所有内容添加到编译时大小的数组中。当然,我正在使用模板。我创造了这个。

template<unsigned int startIndex, unsigned int count>
int AddCollapseArray(int theArray[])
{
    if(count == 1)
    {
        return theArray[startIndex];
    }
    else if(count == 2)
    {
        return theArray[startIndex] + theArray[startIndex + 1];
    }
    else if(count % 2 == 0)
    {
        return AddCollapseArray<startIndex, count / 2>(theArray) + AddCollapseArray<startIndex + count / 2, count / 2>(theArray));
    }
    else if (count % 2 == 1)
    {
        int newCount = count-1;
        return AddCollapseArray<startIndex, newCount/ 2>(theArray) + AddCollapseArray<startIndex + newCount/ 2, newCount/ 2>(theArray)) + theArray[startIndex + newCount];
    }
}

对我来说,这似乎可以最有效地完成工作。我认为除了加法之外的分支和算术将被完全优化。这样做有什么缺陷吗?


不要试图智胜优化器。所有这些复杂的模板机制只会让优化器更难理解您真正想要做什么。

例如,

int f0(int *p) {
  return AddCollapseArray<0, 10>(p);
}

int f1(int *p) {
  return std::accumulate(p+0, p+10, 0);
}

产生的完全相同的组件 http://goo.gl/NQhrgw在 -O3 处发出铿锵声

f0(int*):                                # @f0(int*)
    movl    4(%rdi), %eax
    addl    (%rdi), %eax
    addl    8(%rdi), %eax
    addl    12(%rdi), %eax
    addl    16(%rdi), %eax
    addl    20(%rdi), %eax
    addl    24(%rdi), %eax
    addl    28(%rdi), %eax
    addl    32(%rdi), %eax
    addl    36(%rdi), %eax
    retq

f1(int*):                                # @f1(int*)
    movl    4(%rdi), %eax
    addl    (%rdi), %eax
    addl    8(%rdi), %eax
    addl    12(%rdi), %eax
    addl    16(%rdi), %eax
    addl    20(%rdi), %eax
    addl    24(%rdi), %eax
    addl    28(%rdi), %eax
    addl    32(%rdi), %eax
    addl    36(%rdi), %eax
    retq

假设我们想要处理 100 个元素:

int f0(int *p) {
  return AddCollapseArray<0, 100>(p);
}

int f1(int *p) {
  return std::accumulate(p+0, p+100, 0);
}

这是我们得到的: http://goo.gl/jYZzNI

f0(int*):                                # @f0(int*)
    pushq   %rbp
    pushq   %rbx
    pushq   %rax
    movq    %rdi, %rbx
    callq   int AddCollapseArray<0u, 50u>(int*)
    movl    %eax, %ebp
    movq    %rbx, %rdi
    callq   int AddCollapseArray<50u, 50u>(int*)
    addl    %ebp, %eax
    addq    $8, %rsp
    popq    %rbx
    popq    %rbp
    retq

f1(int*):                                # @f1(int*)
    movdqu  (%rdi), %xmm0
    movdqu  16(%rdi), %xmm1
    movdqu  32(%rdi), %xmm2
    movdqu  48(%rdi), %xmm3
    paddd   %xmm0, %xmm1
    paddd   %xmm2, %xmm1
    paddd   %xmm3, %xmm1
    movdqu  64(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  80(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  96(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  112(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  128(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  144(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  160(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  176(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  192(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  208(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  224(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  240(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  256(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  272(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  288(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  304(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  320(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  336(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  352(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    movdqu  368(%rdi), %xmm1
    paddd   %xmm0, %xmm1
    movdqu  384(%rdi), %xmm0
    paddd   %xmm1, %xmm0
    pshufd  $78, %xmm0, %xmm1       # xmm1 = xmm0[2,3,0,1]
    paddd   %xmm0, %xmm1
    pshufd  $229, %xmm1, %xmm0      # xmm0 = xmm1[1,1,2,3]
    paddd   %xmm1, %xmm0
    movd    %xmm0, %eax
    retq

int AddCollapseArray<0u, 50u>(int*):     # @int AddCollapseArray<0u, 50u>(int*)
    movl    4(%rdi), %eax
    addl    (%rdi), %eax
    addl    8(%rdi), %eax
    addl    12(%rdi), %eax
    addl    16(%rdi), %eax
    addl    20(%rdi), %eax
    addl    24(%rdi), %eax
    addl    28(%rdi), %eax
    addl    32(%rdi), %eax
    addl    36(%rdi), %eax
    addl    40(%rdi), %eax
    addl    44(%rdi), %eax
    addl    48(%rdi), %eax
    addl    52(%rdi), %eax
    addl    56(%rdi), %eax
    addl    60(%rdi), %eax
    addl    64(%rdi), %eax
    addl    68(%rdi), %eax
    addl    72(%rdi), %eax
    addl    76(%rdi), %eax
    addl    80(%rdi), %eax
    addl    84(%rdi), %eax
    addl    88(%rdi), %eax
    addl    92(%rdi), %eax
    addl    96(%rdi), %eax
    addl    100(%rdi), %eax
    addl    104(%rdi), %eax
    addl    108(%rdi), %eax
    addl    112(%rdi), %eax
    addl    116(%rdi), %eax
    addl    120(%rdi), %eax
    addl    124(%rdi), %eax
    addl    128(%rdi), %eax
    addl    132(%rdi), %eax
    addl    136(%rdi), %eax
    addl    140(%rdi), %eax
    addl    144(%rdi), %eax
    addl    148(%rdi), %eax
    addl    152(%rdi), %eax
    addl    156(%rdi), %eax
    addl    160(%rdi), %eax
    addl    164(%rdi), %eax
    addl    168(%rdi), %eax
    addl    172(%rdi), %eax
    addl    176(%rdi), %eax
    addl    180(%rdi), %eax
    addl    184(%rdi), %eax
    addl    188(%rdi), %eax
    addl    192(%rdi), %eax
    addl    196(%rdi), %eax
    retq

int AddCollapseArray<50u, 50u>(int*):    # @int AddCollapseArray<50u, 50u>(int*)
    movl    204(%rdi), %eax
    addl    200(%rdi), %eax
    addl    208(%rdi), %eax
    addl    212(%rdi), %eax
    addl    216(%rdi), %eax
    addl    220(%rdi), %eax
    addl    224(%rdi), %eax
    addl    228(%rdi), %eax
    addl    232(%rdi), %eax
    addl    236(%rdi), %eax
    addl    240(%rdi), %eax
    addl    244(%rdi), %eax
    addl    248(%rdi), %eax
    addl    252(%rdi), %eax
    addl    256(%rdi), %eax
    addl    260(%rdi), %eax
    addl    264(%rdi), %eax
    addl    268(%rdi), %eax
    addl    272(%rdi), %eax
    addl    276(%rdi), %eax
    addl    280(%rdi), %eax
    addl    284(%rdi), %eax
    addl    288(%rdi), %eax
    addl    292(%rdi), %eax
    addl    296(%rdi), %eax
    addl    300(%rdi), %eax
    addl    304(%rdi), %eax
    addl    308(%rdi), %eax
    addl    312(%rdi), %eax
    addl    316(%rdi), %eax
    addl    320(%rdi), %eax
    addl    324(%rdi), %eax
    addl    328(%rdi), %eax
    addl    332(%rdi), %eax
    addl    336(%rdi), %eax
    addl    340(%rdi), %eax
    addl    344(%rdi), %eax
    addl    348(%rdi), %eax
    addl    352(%rdi), %eax
    addl    356(%rdi), %eax
    addl    360(%rdi), %eax
    addl    364(%rdi), %eax
    addl    368(%rdi), %eax
    addl    372(%rdi), %eax
    addl    376(%rdi), %eax
    addl    380(%rdi), %eax
    addl    384(%rdi), %eax
    addl    388(%rdi), %eax
    addl    392(%rdi), %eax
    addl    396(%rdi), %eax
    retq

您的函数不仅没有完全内联,而且也没有矢量化。 GCC 产生了类似的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最有效地将编译时大小的数组的所有元素相加 的相关文章

  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 如何从 .resx 文件条目获取注释

    资源文件中的字符串有名称 值和注释 The ResXResourceReader类让我可以访问名称和值 有办法看评论吗 你应该能够得到Comment via ResXDataNode class http msdn microsoft co
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col

随机推荐

  • 设置缩略图内容类型

    我需要设置Content Type对于缩略图 我已经尝试如下所示 但它不起作用 仍然 它存储为流 天青功能 索引 json var Jimp require jimp module exports context myBlob gt Rea
  • Scala 隐式转换范围问题

    采取这个代码 class Register var value Int 0 def getZeroFlag Boolean value 0x80 0 object Register implicit def reg2int r Regist
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 需要禁用引导时间选择器的输入

    我正在使用 Bootstrap 时间选择器 我已经成功实施了 但我需要的是用户只能在 30 分钟间隙内插入 例如 10 00 10 30 11 00 等 为此我尝试过的是minuteStep如下图所示 效果完美 fantasyleague
  • 将文本粘贴到 Macintosh 上的 emacs 中

    我使用的是 Macintosh 并且使用 终端 作为我的 shell 当我从任何窗口复制文本 通过鼠标拖动 然后鼠标右键菜单 gt 复制 然后将文本 鼠标右键 gt 粘贴 粘贴到运行 emacs 的终端中时 它不会充当粘贴 相反 它就像输入
  • 如何改变android中menuItem的背景颜色?

    我正在以编程方式将菜单项添加到菜单中 我想在选择特定项目时添加背景颜色 如何为 menuItem 添加背景 您的回答将不胜感激 虽然其他答案提供了更改样式 这会影响all菜单项 据我了解 需要更改一个菜单项 我建议你使用android ac
  • Boost:如何从 Epoch 打印/转换 posix_time::ptime(以毫秒为单位)?

    我在转换时遇到问题posix time ptime到由 表示的时间戳time t or posix time milliseconds 或任何其他可以轻松打印的适当类型 来自 Epoch 我实际上只需要打印由posix time ptime
  • Web 服务调用后响应对象中的属性为 null

    我可以在 Fiddler 中看到该对象 但该对象在我这边没有反序列化 有没有人见过这个 响应为空 或 响应包含空值 或 请求为空 或 请求包含空值 几乎总是意味着命名空间不匹配 例如 响应可能包含
  • 构造奎因(自我复制功能)

    有没有人构建过 quine 生成自己源文本的副本作为其完整输出的程序 http www nyx net gthompso quine htm http www nyx net gthompso quine htm 在 R 中 quine 标
  • 使用biopython写入fasta文件时出错

    我使用以下代码将 fasta 序列写入文件 from Bio import SeqIO sequences KKPPLLRR add code here output handle open example fasta w SeqIO wr
  • 检查双精度值的等于和不等于条件

    我在比较两者时遇到困难double values using and 我创建了 6 个双变量并尝试进行比较If健康 状况 double a b c d e f if a b c d e f My code here in case of t
  • Quartz.NET 设置 MisfireInstruction

    我正在使用 Quartz NET 在 C 中工作 并且在 CronTrigger 上设置失火指令时遇到问题 我正在运行安装了 Quartz DB 的 SQL 后端 我有以下代码 可以很好地创建作业和运行调度程序 IScheduler sch
  • 如何将 DataTable 转换为动态对象?

    我怎样才能转换DataTable in IEnumerable
  • 输入数字或 Q 退出

    大家好 我在设定的任务中遇到了一些问题 任务的第一部分是输出具有以下规则的价格表 50 件以内的价格为每件 5 英镑 51 至 80 之间的价格为每张 4 英镑 而 81 至 100 之间的价格为每张 2 50 英镑 使用循环结构和选择语句
  • 查找回收器视图中的第一个可见项目是否是列表的第一项

    我有一个包含 13 个数据项的回收器视图 我想知道列表中的第一项是否可见 我知道像这样的方法findFirstVisibleItemPosition and findLastVisibleItemPosition但他们没有说明第一个可见项目
  • 切换到工作区并在 Xcode 中添加 CocoaPods 后提交 git 吗?

    我刚刚在 Xcode 5 中将 CocoaPods 添加到我当前的项目中 当然 CocoaPods 创建了一个工作区 并且我已在 Xcode 中启动了该工作区 我在工作区中看到了我的项目和 Pods 项目 我的项目从第一天起就处于源代码控制
  • C# .NET 4.0 测试框架?

    如果我没记错的话 NUnit 是单元测试事实上的标准 但我刚刚下载了它 编写了一个简单的测试 然后显然我必须启动 GUI 并加载我的 exe组装 根本就失败了 我尝试编辑 C Program Files x86 NUnit 2 5 7 bi
  • 如何检测不渲染 .png 透明的浏览器

    我有这段代码可以根据一周中的某一天渲染图像 但在 IE6 及更低版本以及可能其他一些浏览器中 它不会呈现 png 不透明度 所以我想稍微改变一下 这样它就会检测到不渲染 alpha 透明度的浏览器 并告诉他们加载这个图像 img horar
  • 从 xsd 生成 cXML 类会引发错误“元素‘uri:ds:Signature’丢失。”

    我正在尝试根据 cXML 1 2 034 版本生成 cXML 类http cxml org http cxml org XSD 由 Visual Studio 转换 我将 cXML dtd 转换为 xsd 然后尝试运行 xsd exe cX
  • 最有效地将编译时大小的数组的所有元素相加

    我正在尝试使用最少量的指令 有效地将所有内容添加到编译时大小的数组中 当然 我正在使用模板 我创造了这个 template