前言

最近在打腾讯广告算法大赛,所以一直在鸽0 0,再加上复赛印象不怎么深刻,所以就随便扯啦。

开源地址:https://github.com/Chadriy/CodeCraft2020


放题

一、规则改动
复赛增加了转账金额的限制,搜索得到的目标环中相邻边必须满足金额限制,即环内任意相邻边 x x x、 y y y需满足 x ∈ ( 0.2 y , 3 y ) x\in (0.2y,3y) x∈(0.2y,3y)和 y ∈ ( 0.2 x , 3 x ) y\in (0.2x,3x) y∈(0.2x,3x),大概就是代码加了个判断而已,然后是环数上限拉到2000w之类的增强。
二、数据集增强
由于初赛数据集被各路大佬扒的差不多了,初赛一个完全图就离谱,于是复赛线上塞了个随机图来做增强。
三、前期准备
一开始我摸了好几天,队友写好了base去陪女票了,线下民间出现了1963w环的数据集。在放榜前,这个数据集很快被大家刷到了20s以内的成绩,我们大概是43s的样子。

练习榜A

刚开始放题的时候,线上数据死性不改,还拿完全图凑数- -。于是大家线下成绩以s为量级,线上第一天又到了1s以内。这时候是正是赛第二次选手情绪集中爆发吧,第一次是初赛最后一天官方限制针对线上数据集不处理的trick。这次官方允诺会加强数据集,所以练习榜分了AB。
这个榜十分短暂,我甚至不记得我做过什么优化…大概第一发就1.0了,然后加了一个小trick到0.88。
trick:

Before:uint circle[THREAD_COUNT]
After:uint circle[(THREAD_COUNT / 4 + 1) * 4]

如上,当时我们用的10线程,然后每个线程单独记录环数,然后定义了一个全局数组来记录对应线程的环数。对齐之后,线上提了10%。
所以来讲讲对齐的各种奇妙结果:

  • 情景1:
    全局变量的定义过程中,有某个变量定义时,长度没有cacheline(鲲鹏128位)对齐,之后的变量首地址都会偏移。最终结果会产生很大影响,因此这里对齐是正优化。
  • 情景2:
    在一个结构体内,假设该结构体是16+32,应该填充一个ushort填充到64,同理32+64应填充到128。然而,16+16与32+32不应该填充。因为对齐会降低cachemiss,在连续访存时,16+16的结构体会一次被读进一个cacheline长度(4个),于是提高了cachehit。于是,压缩内存比地址对齐更重要。除了这种对齐,我们还可以通过设置位段的形式,同时完成二者。譬如结构体内有32+64的两个变量,通过确定其上届,若存储仍有冗余,可以将之拆解为24+40这样(前提是不会溢出)。然后通过设置位段的方法将32+64压缩到xx+xx=64的形式(该策略来自凌少)。
  • 情景3:
    memcpy函数在固定长度、可变长度等多种情况下会编译成不同的指令,通过阅读其汇编源码可知,当长度为16时会被O3编译成一条读内存和一条写内存指令,所以这个对齐很强,尝试了各种魔改,都不如开O3+16位固定长度的memcpy- -。

当然对齐也并不是很大的要素,事实上在之后海海的开源代码中可以看到,大部分情况下,内存紧密排布比cacheline对齐更加重要,因此需要以实验为准。
除此之外,我们代码中的存储也由多维数组改成了动态一维数组的形式,类似于开辟一个内存池,然后变量从中按需取。然后在初赛时,我们对反向搜索时长度为2、3的路径都进行了保存,然而事实上只需要存长度为3的路径。除此之外,金额判定用整数乘法代替除法也是基本操作了。
综上,练习赛A榜最终成绩0.67s,这时候io仍占了很大比重,再加上我们对对齐的理解已经超过了大部分选手,因此封榜时我们跑到了全榜第一(大佬们还没入场)。

练习榜B

B榜对数据集进行了增强,增加了随机图和小菊花图(出度很大的局部图),因此优化空间提高了很多。这次我们开局4s,第一天海子哥已经2.4s了qwq。经过两天的debug,我们发现线上跑10线程就会炸,换回4线程就好了(莫名其妙)。浪费两天时间,成绩来到3.2s。
对于菊花图,我们到最后也没有做有效的处理,短暂的一周我们主要做了如下优化:

  • if判断存在部分冗余,其位置也影响成绩。
  • 逻辑上的些许优化(忘了)
  • 多线程读,线下400+ms->160ms

最后几天我主要对读文件做改进,多线程mmap、多线程归并sort等等,将读+映射+构图的逻辑全部并行,然后将unordered map替换为robin map,线上同步提升0.3s的成绩。然后是未完成的部分,首先是3.5+3.5的搜索方案,即正反向搜索层数在3+4与4+3中切换,以达到理论最优。同时进行了大量的数据分析,比如幂律分布导致线程负载均衡更极端,需要微调等等。同时对于出度很大的菊花图,应该尽量用反向搜索代替正向,在代码里写了switch的策略。当然,都没有什么好的结果。
最终以全国第七收尾,空佬在最后一天通过一个magic提升了0.4s到了榜二。空佬给了我一点提示,一直到最后复赛放题我还在写- -,最后发现我们理解的都不是一个意思。
magic-空佬:通过实验可以得出结论,二维数组访问速度比动态生成的一维数组。于是对于菊花点(出度很大)用二维数组存,对于普通点用一维数组。
magic-蔡总:对于菊花点,其出度很大,因此在正向搜索中只要遇到就会炸。因此可以进行“拆点”,将一个菊花点的邻接表进行拆分。譬如点A其邻接表是平均度的100倍,那么可以将A点拆成A1-A10,各自入度连接不变,出度邻接表进行均分。通过分析我们得知这是一个很大的逻辑优化,但由于时间紧迫,再加上存储结构比较复杂,最终未能实现。
最终全榜第七。

正赛

成也magic,败也magic。
1.50分官方放题,环长度要求变更为3-8,同时金额变为两位浮点数,变动“很小”。
针对规则1,由于进行了循环展开,代码改动很大,一点小小的疏忽就可能崩盘。蔡总开始改4+4,反向用原来的三层+一层打标记实现,我改数据类型和读文件。对于数据类型,我坚决反对用double,因为太慢,于是改为统一乘100到long的形式。一个半小时,debug到手抖,对上了所有线下答案。第一发提交3.2s,后面几发就调了调参数,临场发挥为0。
最终抖到3.19s,全榜第六。
正赛结束,复赛于大多数选手而言,都不是一段愉快的经历,我们也遇到了很多莫名其妙的bug。这里说句题外话,命题组敷衍的态度与出题水准,直接在复赛刷掉了70%的选手,其中还有ddd、魔法少女这样的顶级选手,甚至还在赛后开贴回应到“选手太菜”、“魔鬼参数”等等。果子哥最后几天还在打点滴熬夜solo,结果最后被double精度问题卡掉,空佬也是同样问题被卡。于是出现了很扯淡的情况,练习赛我前面的团队全部没分,真应该把空佬的队名给我们qwq。

结语

复赛办的乱七八糟,不过在这过程中,认识了很多好朋友。练习赛最后几天,我们相互鼓励,交流idea,度过了一段美好的时光,这远比题目本身有趣。然而,最终我的祝福变成了毒奶,只有我一人进到了决赛qwq。
之后心情低落了好几天,爷青无(摔)。

PS:赛后送了空佬一张奶刃2黄金国的卡带,希望能让他高兴一点。

2020华为软件精英挑战赛历程总结——复赛篇相关推荐

  1. 2020华为软件精英挑战赛历程总结——决赛篇

    前言 决赛的过程颇为坎坷,深深的感受到了自身能力的不足,团队的力量有时要远胜个人. 开源地址:https://github.com/Chadriy/CodeCraft2020 放题 复赛结束,还没来得 ...

  2. 2020华为软件精英挑战赛历程总结——初赛篇

    前言 去年懵懵懂懂,一个人从头自闭到尾,到最后也没对上判题器,复赛第十遗憾离场.今年的开端也是十分不顺,我们提交的第一发线上14s,这时候前排已经有0.x的成绩了,一度陷入深深的自我怀疑之中.好在队友 ...

  3. 2020华为软件精英挑战赛历程总结

    前言 历时两个月,终于结束了今年的华为软挑,这感觉就很爆肝.非常感谢队友们的强力输出.还有遇到的的大佬.成研所的小姐姐们,虽然成绩不佳,但还是分享一下我们每个阶段的成长. 首先简单自我介绍一下,我是I ...

  4. 2020华为软件精英挑战赛总结

    2020华为软件精英挑战赛总结 00 赛题描述 01 整体思路 02 数据读取以及正反向图构建 03 多线程找环运动 031 反向DFS 3层构建P3 032 正向DFS 4层找环 04 结果输出 0 ...

  5. 2020华为软件精英挑战赛——总结

    2020华为软件精英挑战赛 github:https://github.com/jadyntao/HuaWei_CodeCraft_2020 队伍:助教小分队(粤港澳赛区) 初赛:0.2102(赛区第 ...

  6. 2021华为软件精英挑战赛总结(复赛第12名)

    2021华为软件精英挑战赛 github 地址:https://github.com/DougZheng/Huawei_software 前言 无意中看到赛题,觉得很有意思,就匆忙在报名截止前几天上了 ...

  7. 2020华为软件精英挑战赛-有向图找环

    初赛找环,复赛还是找环.初赛没有用到权重(金额),复赛对数据进行加强,同时对相邻两次转账的金额做了限制. 初赛用的单线程,最好成绩:0.2854, 进入了32强.复赛用了多线程,A榜最好成绩:6.11 ...

  8. 华为2020软件精英挑战赛初赛、复赛、决赛代码+心得分享

    目录 写在前面 初赛 第一代思路 第二代思路 最终版思路 优化思路 多线程 数据结构设计 输入和输出的优化 复赛 规则描述 优化思路 算法 多线程 数据结构设计 复赛正式赛 总决赛 总结 写在前面 2 ...

  9. 2023华为软件精英挑战赛,探寻软件人才与科技创新的最优解

    作者 | 曾响铃 文 | 响铃说 今天,软件行业正呈现出江河入海一般的大汇流趋势. 一方面是技术的汇流,诸如人工智能等前沿技术与软件行业的深度融合,正全面颠覆软件产品的开发模式和服务逻辑. 另一方面则 ...

最新文章

  1. 翻译机之后,搜狗再推智能硬件产品录音笔
  2. MCU多任务提高实时性
  3. Android中堆unlink利用学习
  4. C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻
  5. RStudio修改快捷键确保每次运行都是从头运行所有代码
  6. java bufferedwriter 写入tab_Java基础-IO流
  7. 利用session防止表单重复提交
  8. linux c 读取摄像头,Linux下onvif客户端获取ipc摄像头 获取能力:GetCapabilities
  9. 吉大计算机考研分数线2021,吉林大学2021考研分数线
  10. 如何自动填充网页表单_流量型称重型充绒机充棉机如何选择,教你轻松辨别全自动填充机器...
  11. NodeJs学习笔记002--npm常用命令详解
  12. iOS UITabBarController
  13. 数据库原理及应用实验二
  14. eviews9.0详细安装步骤
  15. PHP沉思录(转载)
  16. Dart 语言入门基础(一)
  17. 华为账号登录总显示服务器繁忙,愚人节玩笑:华为手机帐号无法登陆,提示网络繁忙...
  18. web播放m3u8文件且进行加密处理
  19. 雷军 50 岁身价破 1000 亿:决定人生胜负的,是这 5 条规律
  20. 我不敢再哭了,因为我怕自己成为职场上的杨超越

热门文章

  1. 《算法0基础100讲》(第7讲)素数判定——866.回文素数
  2. Vue表格绑定数据、添加数据
  3. 火伞云APP盾,您身边的DDoS攻击安全保护专家
  4. 关于STM32空闲中断
  5. Openstack-nova(placement)组件部署流程
  6. MSI和MSI-X对比(五)
  7. 《算法竞赛进阶指南》刷题记录
  8. 【Vue3】李南江老师讲解--个人笔记(二)ref 和 reactive详解
  9. wannier插值能带拟合5
  10. 电脑主板RS232串口硬件设计