Edimetia3D

Edimetia3D

未分类

Lit and FileCheck

Lit And FileCheck Lit 和 FileCheck 是 LLVM 测试中常用的工具, 尽管二者功能上是完全独立的,但是搭配起来使用会显得更加方便. Lit Lit总的来说仅仅是一个 test-launcher, 它的主要功能就是发现测试,执行测试,收集结果. "发现测试"主要依赖于lit.cfg(或lit.site.cfg)文件标记来实现. 当一个目录下包含这个文件时, 那么这个目录就可以被用作lit的测试根目录, lit会自动的递归进入子目录查找测试文件. "执行测试"则相对简单, 每个"lit测试文件"都应该是文本文件,这些文本文件中 RUN: 将被视作标记,这个标记之后的内容就是执行测试的shell指令, 测试指令返回0则认为测试通过, 例如 RUN: echo jojo | grep jojo. 具体来说,

By Edimetia3D

未分类

比较运算符, Min, Max, Sort 和 Order

惭愧,突然发现又是没有blog的一年。这一年不断在尝试搞大新闻,写点大东西,到现在也没憋出来。倒是又在学习新东西的过程中看到了一些零碎的小知识,很有意思. 很巧,这个也是和比较运算符相关的,和一年前的blog竟然有所重合。 还是先上结论: 当需要为类型T定义比较运算符时,所有运算符最好保证语义整体一致 * 一般来说,这很容易达到,我们只需要实现operator<(lhs,rhs),即可引申定义出其余几个比较运算符. * 定义operator<=为 !(rhs < lhs) * 定义operator>为 rhs < lhs * 定义operator>=为 !(lhs < rhs) * 定义operator= 为!(lhr < rhs) && !(rhs < 1hs) * 定义operator!= 为

By Edimetia3D

布道

IEEE 754 的 inf 比较问题

首先上结论: 当涉及浮点数比较时,一定要考虑比较符号两侧都是inf的情况. 原因: inf==inf,inf<=inf,inf>=inf 这三个比较都为真(-inf同理),而这种结果可能与我们的期望不符. 解决方法: 1. 如果为真是可以接受的,那么直接使用比较运算符,例如a<=b 2. 如果为真是不可以接受的,那么应当使用作差,例如(a-b)<=0, 这种情况下,当a和b都为inf时,inf之间的运算会输出NaN,从而导致比较结果为false 例如,我有这样一个应用场景: 有射线R和两个平面S0及S1,我们需要求射线R与平面S0的交点p0,以及射线R与平面S1的交点P1. 且要求p0不能比p1离射线起点更远(可以重合) 假如我们用直线的参数方程来描述交点,显然,上面的目标很容易用 t0<=t1 来描述. 此时就可能出现 inf<

By Edimetia3D

记录

KD树与SKD树

KD树与SKD树 首先给出两个搜到的有点内容的KD树文章,论述的比我说的更完整(更冗长),可以先看,也可以看完本文再看. * https://www.zybuluo.com/l1ll5/note/967681 * http://www.whudj.cn/?p=920 主体思想 * KD树和SKD树都使用坐标轴对齐的最小包围盒来描述空间. * 例如,平面内,一堆点的点集对应的空间可以用点A=(min(all_x),min(all_y)),B=(max(all_x),max(all_y)) 对应的矩形空间来描述. 当点的个数变为1时,这个矩形空间也会自然地退化为一个点. * 构建时的主要思想: 每个节点node都对应了一个空间box(node),node->plane用一个超平面把这个空间box(node)一分为二,记为sub_left,

By Edimetia3D

记录

设计模式

For C/C++ user 很多设计模式相关的资料都是用Java来描述的,有必要简单补充一下Java和C++在OOP技术层面上的区别 * Java不支持任何形式的运算符重载 * Java明确区分接口和类,类只能从一个类派生,但是一个类可以实现多个接口 * 在Java中,所有方法默认是虚(virtual)的 * 对CPP而言,Java风格的接口可以视为一个只有pure virtual成员函数的基类,称为Interface * implement,is-a(inherit),has-a * implement: 特指继承Interface,并通过override实现其中函数的行为. * is-a: 特指继承普通类后,普通类和基类的关系. * has-a: 特指持有某个对象. 杂谈 * 设计模式可以说就是各种各样的"OOP最佳实践方法". 一个设计模式对应了一种组织代码的风格,对应了一种解决问题的策略. * 设计模式可以说是程序员的"行话",使用"行话"有利于交流,但是并不一定有利于问题的解决,简单优雅的解决问题总是

By Edimetia3D

C++系列

SomeCpp

零碎知识点 * fflush仅仅是为了输出而设计的, 标准中并没有说明它对输入缓冲的效果. * 一元运算符和=是右结合的,这和<<是完全不同的,a=b=c意味着a=(b=c),b=c将先执行,而a<<b<<c则是(a<<b)<<c,a<<b将先执行. * C++11后引入了thread_local型的生命周期,这种对象和线程的生命周期是一致的 * C++11中很多类型都支持列表初始化,a = {value1,value2...} * 列表初始化会额外检测是否可能存在信息丢失,如果可能存在丢失,则无法通过编译期检查. * 对于自定义类,支持列表初始化意味着存在这样的ClassName(initializer_list&

By Edimetia3D

C++系列

Some Multi Thread

C++标准库提供的 mutex 在大部分场合都足以保证线程安全, 但是当问题变得更加极端时,就可能需要使用lockfree风格的并行编程了. 而为了正确实现lockfree, 你将打开一扇新的大门, 接下来的名词都是在学习过程中必须正确理解的: memory model, reordering, weak(relax), strong(strict), fence, barrier, release, acquire, seq_cst, consume, mutex, futex, lockfree(lockless), synchronize-with, happens-before, ABA, DCLP, 背景 在单核时代,CPU设计中引入了很多特性,其中很重要的一点就是乱序执行,乱序执行的基本原则是:乱序执行的最终效果应当和顺序执行一致,这个原则在单线程下是比较容易保证的.例如,对于下面的代码,先写入a还是先写入b都不影响后序的指令执行的正确性,所以编译器及硬件都可以自行选择先执行哪一个. a = 8; b = 9; 当进入并行环境之后,乱序执行的基本原

By Edimetia3D

布道

Python for C++ Programner

这里谈一下个人的学习建议. 首先可以阅读官方的入门教程, 看完这一部分, 对于一个熟练的C++程序员, 应该可以凑合写出可堪一用的代码了. 对于大部分不以Python为主要工作语言的开发者,到此基本就足够了. 如果有时间,我建议直接阅读Python in a Nutshell第七章之前的内容(不含第七章),并不用完全看懂,大部分细节也不用去记忆,只需要看完即可,至此,你就能基本了解Python的运行机制, 写出质量稳定可控(不会存在低级错误)的代码了. 上面两步完成后, 对一个熟悉C++的程序员而言, 基本任何Level的Python资料都可以看了. 你可以继续看Python in a nutshell中感兴趣的部分,也可以选择Fluent Python. 在有相当多的开发经验之后,可以阅读Python Cookbook. 如果仍然想进一步深入, 那么你应该直接学习CPython解释器的实现,Python Developer’s Guide可以作为一个入口. 最后,本文仅仅简单扼要的说明了Python和C++不同的一些特性, 可以作为补充阅读. 书评

By Edimetia3D

C++系列

[Cpp基础][09]C++11多线程编程基础

C++11为多线程开发准备了一套标准的基础设施,主要为<thread>,<mutex>,<condition_variable>, 这套组件基本是"pthread"的标准化.本文主要介绍C++11多线程开发相关的基础内容.如果需要更多的细节,可以直接google或者查手册进行了解. 可调用对象 可调用对象在C++ 11中是非常重要的概念, 它使得"函数"变得更加像对象. 线程库完整的支持可调用对象. * 支持()运算符的对象都是可调用对象,这些工具的设计比较独立,可以在使用时再查reference,常见的有 * bind创建的对象 * lambda * 重载了()的类 * 函数/函数指针 * function<T>. std::thread * 标准库提供了std::thread来进行基础的线程管理,

By Edimetia3D

C++系列

C++ OOP编程综述

嵌套类和局部类 * 定义在类X内的类Y称为嵌套类,它就是一个普通类,只不过使用的作用域被限制了. * 定义在函数内的类Y称为局部类,这种类限制很多,主要用于在语言层面支持Lambda,实践中基本不用. struct(class)的内存布局 * C++的struct和class实例大小不会为0,即便它内部没有任何数据变量.主要是因为编译器总是需要为实例分配内存,使得对象能获得有效的地址,且不同对象的地址总应该是不同的. * 类型布局相关的名词有很多,如POD,Aggragate,naive等,具体我也不是很清楚,总之很麻烦. * 如果需要把sturct或class对象通过C风格直接从内存层面管理(如memcpy),那么要求它的内存布局是平凡的. * 只要类型涉及到virtual, 那类型实例的首地址存储的一定是vptr, 涉及virtual只需满足任意一个条件: * 直接或间接使用虚继承 * 直接或间接使用虚函数 一般规则 C++对象的内存布局对于理解多继承/虚继承非常重要, 基本要关注的有三点 1

By Edimetia3D