雲計算

雲計算

AI崛起,阿里的科技孵化力|甲子光年

塑造者No.56 阿里是从什么时候开始变成一家世人眼中的科技公司的? 至少2012年时不是。 当时浙江大学计算机学院的毕业生都不愿意去同城的阿里,他们认为百度才是极客的理想目的地,而阿里是个“电商公司”。 甚至到2017年时,也不算非常明显。 否则,当年3月9日的黄龙体育场里,在阿里成立18年来举办的首届阿里巴巴技术大会上,阿里巴巴CTO张建锋也不会特意强调,“阿里巴巴的商业太成功了,所以掩盖了阿里巴巴在技术上的光芒”。 而站在2019年回看,阿里的科技之力已深入人心。 这种新形象由多块拼图汇聚而成,比如: 一群疯子是如何在“疑似骗子”的王坚的带领下,流汗、流泪,死磕出自研的阿里云的。 10年间,以北京汇众大厦的一行代码“##Created at 2009-02-19 by Apsara”为起点,“飞天”是如何更迭、裂变,成为连接全球49个地区,绵延上百万台服务器的庞大复杂系统的。 漆远、金榕、华先胜、贾扬清等业界知名科学家是如何陆续被阿里吸引的。 逐渐成为程序员心中Java圣地的阿里,是如何掀起一场Java规范风暴,攻克了万人技术公司在研发、维护大规模代码上的共同难点的。 …… 正是这一群群人的一个个故事,一点点筑就了阿里的科技形象。 而所有故事中,最新、最不可忽视的一个是2017年10月横空出世的达摩院。 阿里科技看达摩,达摩先锋看AI。 […]

雲計算

带你读《OpenCV 4计算机视觉项目实战 (原书第2版)》之三:学习图形用户界面

点击查看第一章点击查看第二章 第3章 学习图形用户界面 在第2章中,我们学习了OpenCV的基本类和结构,以及最重要的类Mat,还学习了如何读取和保存图像及视频,以及图像在内存中的内部结构。我们现在已准备好使用OpenCV,但是,在大多数情况下,我们需要使用许多用户界面来显示图像结果,并检索用户与图像的交互。OpenCV为我们提供了一些基本的用户界面,以便创建应用程序和原型。为了更好地理解用户界面的工作原理,我们将在本章最后创建一个名为PhotoTool的小应用程序,在这个应用程序中,我们将学习如何使用滤镜和颜色转换。本章介绍以下主题: OpenCV基本用户界面 OpenCV Qt界面 滑块和按钮 高级用户界面:OpenGL 颜色转换 基本滤波器 3.1 技术要求 本章需要熟悉基本的C++编程语言,所使用的所有代码都可以从以下的GitHub链接下载:https://github.com/PacktPublishing/Learn-OpenCV-4-By-Building-Projects-Second-Edition/tree/master/Chapter_03 。代码可以在任何操作系统上执行,尽管它只在Ubuntu上测试过。 3.2 OpenCV用户界面介绍 OpenCV拥有自己的跨操作系统用户界面,它使开发人员能够创建自己的应用程序,而无须学习复杂的用户界面库。OpenCV用户界面是基础性的,但是它为计算机视觉开发人员提供了创建和管理软件开发的基本功能。所有这些功能都是原生的,并针对实时应用进行了优化。OpenCV提供两种用户界面选项: 基于原生用户界面的基本界面,适用于Mac OS X的cocoa或carbon,以及适用于Linux或Windows用户界面的GTK,这些界面在编译OpenCV时被默认选择。 基于Qt库的略微更高级的界面,这是跨平台的界面。必须在编译OpenCV之前,在CMake中手动启用Qt选项。

雲計算

带你读《自然语言处理的认知方法》之一:延迟解释、浅层处理和构式:“尽可能解释”原则的基础

智能科学与技术丛书点击查看第二章点击查看第三章自然语言处理的认知方法Cognitive Approach to Natural Language Processing [英] 伯纳黛特·夏普(Bernadette Sharp)[法] 弗洛伦斯·赛德斯(Florence Sèdes)[波兰] 维斯拉夫·卢巴泽斯基(Wies?aw Lubaszewski)徐金安 等译 第1章 延迟解释、浅层处理和构式:“尽可能解释”原则的基础 本章将讨论“尽可能解释”原则,这条原则指的是在没有足够的信息可用之前,对处理机制进行延迟。这条原则依赖于对基础单元—语块的识别,识别语块则通过语块的基本特征来实现。语块是待处理的输入的分段。在一些情况中,基于它们所具有信息的可理解性,语块可以是具有语言学结构的元素。在其他情况中,语块只是简单的分段。语块存储在工作记忆的缓冲区中,并在可以分组的时候递增地进行分组(基于内聚力度量),逐步识别输入的不同结构。对语言输入的整体解释不再基于逐字翻译的机制,而是基于对输入结构的分组,这些结构构成了“尽可能解释”原则的基础。 1.1 引言 自然语言处理、语言学和心理语言学从不同角度揭示了人类处理语言的方式。然而,这几个方面的知识仍然很零散:传统研究通常关注的是语言处理子任务(如语言习得)或模块(如形态学、句法),并没有形成统一的框架。要找到一个能将不同信息源统一到一个特定体系结构中的通用模型非常困难。存在这样一个问题:我们仍然对语言的不同维度(韵律、句法、语用、语义等)如何相互作用知之甚少。一些语言学理论,特别是构式语法(construction grammar)[FIL 88,GOL 03,BLA 16],提出了一些方法,使聚合和建立不同维度之间的关系变得可能。这些框架依赖于构式的概念,后者是根据不同层次(词汇、句法、韵律等)的特定属性所链接成的一组单词,并且与特定含义相关联,该含义通常是非清晰的或可组合理解的(如习语或词组)。有趣的是,这些理论也为整合多模态信息(语言和非语言)提供了一个框架。解释一个构式(即获取其相关的意义)是所有维度交互作用的结果。在这种架构之下,对语言生成的处理不是一个线性过程,而是需要借助机制来对构式进行全局识别。与增量体系相反(参见[FER 02,RAY

雲計算

带你读《量子编程基础》之三:量子程序的语法与语义

点击查看第一章点击查看第二章 第3章 量子程序的语法与语义在2.3节中,我们使用底层的量子计算模型(即量子线路模型)来介绍量子算法。那么, 我们如何为量子计算机设计和实现高级量子编程语言呢?从本章起,我们将系统地介绍量子 编程的基础知识。首先,让我们看看如何直接扩展经典的编程语言,使其能够为量子计算机编程。正如1.1 节和1.2节所述,该问题是量子编程早期研究中的主要关注点。本章对一类经典程序的简单 量子化扩展进行研究 —— 使用经典控制的量子程序,即程序处于数据叠加范式。121节 已经对这类量子程序的设计思路进行了简单介绍。本章将会对这类程序的控制流进行简要 讨论。本章分为三部分: while语句是许多经典编程语言的“核心”。本章的第一部分介绍while语句的量子 化扩展,由3.1-3.3节构成。其中,3.1节定义量子while语句的语法,3.2节和3.3 节分别介绍它的操作语义和指称语义。在这部分中,我们还简单地介绍了量子域理论,该理论是刻画量子while语句中循 环的指称语义所必需的。为了增强可读性,关于量子域的一些引理的冗长证明被推迟 到本章末尾的单独部分一3.6节。 第二部分是3.4节,这部分将通过增加(带经典控制的)递归量子程序来扩充量子 while语句。这部分还对递归量子程序的操作语义和指称语义进行了定义。此处同样 —需要使用量子域理论来处理指称语义。 第三部分是3.5节,这部分将通过一个例子来说明如何使用本章定义的编程语言来实现Grover量子搜索。

雲計算

面向索引、模型、检索联合优化的下一代推荐技术 | NIPS 2019 论文解读

面向索引、模型、检索联合优化的下一代推荐技术 点击下载论文 一. 背景 搜索,推荐和广告是互联网内容提供商进行价值创造的核心业务,在阿里巴巴这一世界上最大的电子商务交易平台上,搜索,推荐和广告业务同样具有举足轻重的意义和价值。搜索、推荐和广告看似业务形态不同,其实技术组成却是非常相通的。从推荐的视角看,搜索可以认为是一种带query相关性约束的推荐,而广告则是叠加了广告主营销意愿(价格)约束的推荐,所以推荐技术的创新对推动搜索、推荐和广告业务技术的整体发展具有基础性的作用。 从技术演进的角度,推荐算法近年来也在不断的更新换代。从限定在一个有限的历史兴趣范畴内推荐的第一代基于统计的启发式规则方法(代表算法Item-based Collaborative Filtering, Item-CF)到第二代基于内积模型的向量检索方法,推荐技术打开了候选子集检索范围的天花板。然而,向量检索方法限定了内积模型这种用户-商品偏好度量方式,无法容纳更加先进的打分模型(例如带有Attention结构的深度网络)。为了在全库检索和效率约束的基础上进一步打开推荐技术中模型能力的天花板,此前阿里妈妈精准定向广告业务团队自主提出了新一代任意深度学习+树型全库检索推荐算法(Tree-based Deep Model,TDM)深度树匹配推荐技术,在大规模推荐问题上取得了显著的效果提升。本次被NeurIPS 2019接收的这篇论文,介绍了该团队在数据驱动的模型、索引、检索算法联合优化上取得的最新研究成果。 二. 现有体系存在的问题 如下图所示,在大规模任务中,搜索,推荐和广告的系统通常由模型,索引和检索算法三大组件组成。模型计算单个用户-对象的偏好概率,索引将所有商品有序地组织在一起,检索算法根据模型的输出在索引中召回最终的推荐结果。三者共同决定了召回质量且存在内在联系。 然而,以推荐为例,现有的推荐体系对模型索引和检索的相互联系往往没有做充分的考量。从联合调优这一视角出发,对现有的几代推荐体系的代表算法存在问题分析如下: 在Item-CF中,倒排索引根据Item之间某种自定义的相似度量建立,检索过程则是根据用户历史行为在倒排索引中查询候选集后排序截断,模型在排序过程中对候选集中的Item根据某种自定义的规则进行打分。在系统中,模型和检索被规则固化,没有学习调优。 在向量检索的模式中,系统会分别为用户和商品学习一个向量表达,其内积作为用户对商品的偏好程度的预测。检索等价于用户向量在商品向量集合中的kNN最近邻检索,在大规模问题中,可以采用近似的最近邻索引结构来加速检索。在建立向量检索推荐系统的过程中,模型训练的目标是准确的预测单个用户-对象的偏好概率,而kNN检索索引建立的目标则最小化近似误差,二者的优化方向并不一致。同时,内积形式的偏好预测表达能力有限,无法容纳更加先进的打分模型。 在TDM中,我们通过交替迭代优化模型和树结构再加之无参数的逐层beam search检索过程进行了模型、索引和检索联合优化上的实践和创新。然而在TDM中,模型的优化和树结构索引的学习二者的优化目标也不完全一致,这可能导致二者的优化相互牵制而导致最终整体效果次优。特别是对于树结构索引,模型训练样本的构造和检索路径的选择与树结构具有更加紧密的联系,因此其质量好坏尤为重要。

雲計算

Understanding and Improving Layer Normalization | NIPS 2019 论文解读

本文对NIPS 2019录用的论文Understanding and Improving Layer Normalization做出详细的解读,敬请批评指正。 点击下载论文 摘要:这项研究针对的是目前非常常用的技术layer normalization (LN)。LN类似于batch normalization,也是一种深度学习的归一化的技巧。LN主要作用于层的维度,一般对神经网络中间层的表示的分布进行归一化。尤其在最近大火的Transformer等模型中,LN起到非常重要的作用。然而,一直以来我们并不知道为什么LN有效。这篇文章则对LN的作用进行了研究。作者们认为,前向归一化并非LN起作用的唯一因素,均值和方差也是重要原因。它们改变了后向梯度的中心和范围。同时,作者还发现,LN的参数,包括bias和gain,并非总是能够提升模型表现,甚至它们可能会增加过拟合的风险。因此,为了解决这个问题,作者们提出了自适应的LN(简称AdaNorm)。AdaNorm将LN中的bias和gain替换成线性映射函数的输出。这个函数能够自适应地根据不同的输入调整权重。作者们在七个数据集上做了实验都表明AdaNorm能够取得更好的效果。同时可以看到,AdaNorm缓解了过拟合的问题,并且给训练带来更好的收敛效果。 一、引言 继BN之后,学术界提出了LN,针对的是RNN模型,后来科研人员发现LN对于基于自注意力的模型非常有效。典型的例子就是LN在Transformer中的大量使用。LN帮助更快地训练Transformer模型。然而,LN的成功一直是个疑问。一种解释是前向归一化提升了分布的稳定性,但最新研究则表明BN的效果和输入分布的稳定性没有关系,而是让优化的损失更加平滑。大家依然不清楚为何LN有效。 在这项工作中,作者通过分析提出了几个重要的观点,并提出了一种新的归一化的方法。作者们指出,前向归一化、以及均值和方差的导数都对LN非常重要。前向归一化并非成功的唯一因素。作者们通过一种叫DetachNorm的方法,说明了均值和方差的导数的重要性。作者们还指出,因为LN的参数,包括bias和gain,会提升过拟合的风险,它们并非总是对模型起到正向作用。实验表明,将bias和gain从LN中去掉并步总是会影响模型表现。通过对比分析不同情况下的损失函数曲线,作者们认为bias和gain会增加过拟合的风险。 因此作者们提出了AdaNorm的方法,下文将会对AdaNorm做详细的介绍。 二、Layer Normalization和相关实验数据集 LN类似于BN,可以用比较简单的式子表达: 其中的b和g则是文章中提到的bias和gain。 在这里先简单介绍一下实验用的数据集,后面的分析与之相关。本研究在5个任务上的7个数据集做了实验,其中包括机器翻译的IWSLT

雲計算

Learning Disentangled Representations for Recommendation | NIPS 2019 论文解读

点击下载论文 1. 背景 近年来随着深度学习的发展,推荐系统大量使用用户行为数据来构建用户/商品表征,并以此来构建召回、排序、重排等推荐系统中的标准模块。普通算法得到的用户商品表征本身,并不具备可解释性,而往往只能提供用户-商品之间的attention分作为商品粒度的用户兴趣。我们在这篇文章中,想仅通过用户行为,学习到本身就具备一定可解释性的解离化的用户商品表征,并试图利用这样的商品表征完成单语义可控的推荐任务。 2. 什么是解离化表征? 图表 1 截图取自[1] 学习解离化表征的原因和人类认知的Binding Problem (BP) [3]有关。如上图所示,当我们看到一副上面四张图片时,我们可以识别两种较为独立的语义元素,即颜色、形状和位置,这个过程对应Segregation Problem (BP1)。如果我们学到的表征向量中,不同的维度能够分别代表不同的语义,我们称这样的表征是Disentangled的,反之如果某一维对应多种语义,则称该表征是Entangled的;而我们通过这些识别独立的语义元素进而可以组合生成下面四张新的图片,这个过程对应Combination Problem (BP2)。这里假设我们有一个生成模型,能通过BP1学到图片的Disentangled的表征,我们通过调整表征中单个维度的值即可达到只改变某个语义而不影响其他语义的生成,例如把绿色的方块变成绿色的心形,颜色位置不变。除了和人认知过程比较切合,还可以提供可控制的生成之外,学习解离化的向量表征的鲁棒性更好,对测试数据的分布相比而言敏感度较低,同时也有较好的解释性。用户-商品解离化表征:在电商系统中,拥有大量的用户、商品标签以及庞大的用户行为数据,如果可以通过这些数据学习解离化的用户和商品表征,将对推荐可解释、认知推理、营销等工作产生非常积极的影响。而我们此次的工作,是用户-商品解离化表征工作的一个开端,因此我们仅使用到用户行为数据,并不涉及任何商品属性以及用户特征。我们探索,从用户行为当中,能否得到一些认知相关的决策因素并以可解离的方式对商品和用户进行表示。具体来说,我们关注这样的两个和认知相关的子任务:a) 商品在人的认知空间中,他们是如何表征的,这样的表征是否具有可解释性,例如是否能找到的对应的某一维就能够代表一个独立的“语义”。类似的,人在这个空间下的表征,是否也具有这样的语义。联系解离化表征(Disentangled Representation Learning)在图像数据上的发展,我们探索其是否能从离散数据,特别是用户行为数据上学习到类似的结果。b)

雲計算

四川广电网络、阿里云、数梦工场强强联手 共建“智慧广电城市大脑”

“智慧广电城市大脑”合作协议签署现场 2019年11月12日,四川省有线广播电视网络股份有限公司、阿里云计算有限公司、杭州数梦工场科技有限公司在杭州签署共建四川广电“智慧广电城市大脑”合作协议。 阿里巴巴集团副总裁华先胜、阿里云智能副总裁李国欢、四川广电网络公司总经理杨杪、数梦工场执行总裁郑志松出席了签约仪式。 四川广电网络公司近年来深耕“高清四川 智慧广电”建设,形成了健全的云管端一体的网络运营和服务体系。重点拓展公共和行业领域视频服务。建设运营有以视频智能安防为基础服务的超500个智慧社区(乡村),在雪亮工程等领域建设运营超过10万路视频点位。开发推广了校餐安、智慧校园和酒店人证系统、平安小区、雪亮工程+爱家等基于视频识别的典型应用。 目前,公共和行业视频服务正从重点位覆盖到向重智能化应用快速升级,依托四川广电深厚的区域资源和运营能力,阿里云基于飞天云平台,向四川广电网络开放达摩院深层视频算法,协助四川广电对海量公共视频实施即时结构化处理。中国大数据、数据智能领军企业数梦工场,近年来,将智能视频技术深度应用于公共服务领域,积累了丰富经验,本次合作中,将联合四川广电组建专门团队,针对不同场景深度开发视频智能处理的程序性处理方式,为城市管理、交通调度、应急处置、社区家庭安防、老人小孩看护等提供即时的全局态势感知、安全隐患智能分析、安全事件智能识别、联动应急处置等成套智慧解决方案,不断提升“智慧广电城市大脑”感知和处置能力。

雲計算

带你读《基于CUDA的GPU并行程序开发指南》之一:CPU并行编程概述

高性能计算技术丛书点击查看第二章点击查看第三章基于CUDA的GPU并行程序开发指南GPU Parallel Program Development Using CUDA [美]托尔加·索亚塔(Tolga Soyata) 著唐 杰 译 第1章 CPU并行编程概述本书是一本适用于自学GPU和CUDA编程的教科书,我可以想象当读者发现第1章叫“CPU并行编程概述”时的惊讶。我们的想法是,本书希望读者具备较强的低级编程语言(如C语言)的编程能力,但并不需要具备CPU并行编程的能力。为了达到这个目标,本书不期望读者有CPU并行编程经验,但通过学习本书第一部分中的内容,获得足够多的CPU并行编程技巧并不困难。不用担心,最终目标是学会GPU编程,因而在学习CPU并行编程的这部分时,我们并不是在浪费时间,因为我在CPU世界中介绍的几乎每一个概念都适用于GPU世界。如果你对此持怀疑态度,下面是一个例子:线程ID,或者称之为tid,是多线程程序中一个正在执行的线程的标识符,无论它是一个CPU线程还是GPU线程。我们编写的所有CPU并行程序都将用到tid概念,这将使程序可以直接移植到GPU环境。如果你对线程不熟悉,请不要担心。本书的一半内容是关于线程的,因为它是CPU或GPU如何同时执行多个任务的基础。 1.1 并行编程的演化 一个自然而然的问题是:为什么要用并行编程?在20世纪70年代、80年代甚至90年代的一部分时间里,我们对单线程编程(或者称为串行编程)非常满意。你可以编写一个程序来完成一项任务。执行结束后,它会给你一个结果。任务完成,每个人都会很开心!虽然任务已经完成,但是如果你正在做一个每秒需要数百万甚至数十亿次计算的粒子模拟,或者正在对具有成千上万像素的图像进行处理,你会希望程序运行得更快一些,这意味着你需要更快的CPU。在2004年以前,CPU制造商IBM、英特尔和AMD都可以为你提供越来越快的处理器,处理器时钟频率从16 MHz、20 MHz、66 MHz、100 MHz,逐渐提高到200 MHz、333 MHz、466 MHz……看起来它们可以不断地提高CPU的速度,也就是可以不断地提高CPU的性能。但到2004年时,由于技术限制,CPU速度的提高不能持续下去的趋势已经很明显了。这就需要其他技术来继续提供更高的性能。CPU制造商的解决方案是将两个CPU放在一个CPU内,即使这两个CPU的工作速度都低于单个CPU。例如,与工作在300 MHz速度上的单核CPU相比,以200

雲計算

带你读《基于CUDA的GPU并行程序开发指南》之二:开发第一个CPU并行程序

点击查看第一章点击查看第三章 第2章 开发第一个CPU并行程序本章主要关注的是理解第一个CPU并行程序imflipP.c。注意,文件名末尾的“P”表示并行。开发平台对于CPU并行程序来说没有任何区别。在本章中,我将逐步介绍有关并行程序最主要的概念,当我们在第二部分开发GPU程序时,这些概念将很容易地应用于GPU编程。你可能已经注意到,我从不说GPU并行编程,而是GPU编程。这就像不需要说一辆带轮子的汽车,说一辆车就足够了。换句话说,根本没有GPU串行编程,这意味着即使你有100 000个可用的GPU线程,但却只使用一个!所以,按照定义,GPU编程就意味着GPU并行编程。 2.1 第一个并行程序 现在是编写第一个并行程序imflipP.c的时候了,它是我们在1.4节中介绍的串行程序imflip.c的并行版本。为了并行化imflip.c,我们需要在main()函数中创建多个线程并让它们各自完成一部分工作后退出。在最简单的情况下,如果我们尝试运行一个双线程的程序,main()将创建两个线程,让它们各自完成一半的工作,合并线程然后退出。在这种情况下,main()不过是各个事件的管理者,它没有做实际的工作。为了实现我们刚刚描述的内容,main()需要能够创建、终止和管理线程并将任务分配给线程。Pthreads库的部分函数可以帮助它完成这些任务。Pthreads只能在符合POSIX标准的操作系统中工作。讽刺的是,Windows不符合POSIX标准!但是,在POSIX和Windows之间执行某种API到API的转换后,Cygwin64允许Pthreads代码在Windows中运行。这就是为什么本书描述的所有东西都可以在Windows中使用,也是在你的计算机是一台Windows PC的情况下,我推荐Cygwin64的原因。以下是我们将要使用的一些Pthreads库函数: pthread_create()用于创建一个线程。 pthread_join()用于将任何给定的线程合并到最初创建它的线程中。你可以将“合并”过程想象成“毁灭”线程,或者父线程“吞食”刚刚创建的线程。 pthread_attr()用于初始化线程的各项属性。 pthread_attr_setdetachstate()用于为刚刚初始化的线程设置属性。 2.1.1 imflipP.c中的main()函数 我们的串行程序imflip.c(如代码1.1所示)读取一些命令行参数,并按照用户的命令对输入图像进行垂直或水平翻转。同样的翻转操作重复奇数次(例如129),用以改进由clock()获取的系统时间的准确性。代码2.1和代码2.2显示的都是imflipP.c中的main()函数,不同之处在于:代码2.1标注的是“main(){…”,这表示main()的“第一部分”,后面所跟的“…”进一步强调了这一点。这部分用于命令行参数解析和一些常规操作。在代码2.2中,“main() …}”后部的符号与2.1相反,“…”在前,表示这是main()函数的“第二部分”,该部分用于启动线程和给线程分配任务。为了提高可读性,我可能在这两部分代码中重复一些代码,例如使用gettimeofday()获取时间戳,使用ReadBMP()进行图像读取等,稍后将详细介绍ReadBMP()。这将使读者能够清楚地了解这两个部分的开始和连接处。你可能已经注意到,如果完全列出一个函数的代码,就会使用“func(){…}”来表示。当一个函数和它前后的代码同时被列出时,用“… func(){…}”来表示,意思是“一些常规代码…func()完整的代码。”下面是main()函数中命令行解析的部分,命令行参数在argv[]数组中给出(总共有argc个)。如果用户输入的参数个数不对时会报错。用户指定的翻转方向存放在一个名为Flip的变量中备用。全局变量NumThreads也是基于用户输入确定的,稍后将在实际执行翻转操作的函数中使用。 2.1.2 运行时间 当有多个线程执行时,我们希望能够量化加速倍数。在串行代码中我们使用clock()函数,它包含在time.h头文件中,精度仅为毫秒级。我们将在imflipP.c中使用的gettimeofday()函数能够使精度达到μs。gettimeofday()需要包含sys/time.h头文件,并且给一个结构的两个成员变量提供时间:一个是给.tv_sec成员变量设置以秒为单位的时间,另一个是给.tv_usec成员变量设置以微秒为单位的时间。这两个成员变量都是int类型,在输出之前联合生成一个双精度的时间值。值得注意的是,计时的准确与否不取决于C函数本身,而取决于硬件。如果你的计算机的操作系统或硬件无法提供μs级的时间戳,gettimeofday()将只提供从操作系统获得的最佳结果(操作系统从硬件的时钟单元获得该值)。例如,即使使用gettimeofday()函数,由于Cygwin64依赖于Windows API,Cygwin64的精确度也不会达到μs。 2.1.3 imflipP.c中main()函数代码的划分 我有意避免在一个代码片段中列出长长的main()函数代码。这是因为,从第一个示例中可以看出,代码2.1和代码2.2的功能完全不同:代码2.1用于获取命令行参数,解析它们以及向用户发出警告。而代码2.2用于创建与合并线程的“酷动作”。大多数情况下,我会按照类似的方法来安排我的代码,并尽量关注代码的重要部分。代码2.1:imflipP.c …

Scroll to Top