小编Dra*_*rgy的帖子

Objective-C中的typedef枚举是什么?

我不认为我从根本上理解它enum是什么,何时使用它.

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;
Run Code Online (Sandbox Code Playgroud)

这里真的被宣布了什么?

enums typedef objective-c

1081
推荐指数
8
解决办法
43万
查看次数

如何确定2D点是否在多边形内?

我正在尝试在多边形算法中创建一个快速 2D点,用于命中测试(例如Polygon.contains(p:Point)).对于有效技术的建议将不胜感激.

graphics performance polygon collision-detection point-in-polygon

473
推荐指数
15
解决办法
26万
查看次数

Branchless K-means (or other optimizations)

Note: I'd appreciate more of a guide to how to approach and come up with these kinds of solutions rather than the solution itself.

I have a very performance-critical function in my system showing up as a number one profiling hotspot in specific contexts. It's in the middle of a k-means iteration (already multi-threaded using a parallel for processing sub-ranges of points in each worker thread).

ClusterPoint& pt = points[j];
pt.min_index = -1;
pt.min_dist = numeric_limits<float>::max();
for (int i=0; i …
Run Code Online (Sandbox Code Playgroud)

c++ optimization performance

59
推荐指数
5
解决办法
2351
查看次数

跳过清单,他们真的表现得和Pugh纸张一样好吗?

我正在尝试使用最小的额外内存开销实现一个与BST一样好的跳过列表,目前即使不考虑任何内存限制,我的SkipList实现的性能也远远不是一个非常天真的平衡BST实现 - 所以说,手工制作的BTS :) -

作为参考,我使用了William Pugh PUG89的原始论文以及我在Sedgewick -13.5-的C中算法中发现的实现.我的代码是一个递归实现,这是插入和查找操作的线索:

sl_node* create_node()
{
    short lvl {1};
    while((dist2(en)<p)&&(lvl<max_level))
        ++lvl;
    return new sl_node(lvl);
}

void insert_impl(sl_node* cur_node,
        sl_node* new_node,
        short lvl)
{
    if(cur_node->next_node[lvl]==nullptr || cur_node->next_node[lvl]->value > new_node->value){
        if(lvl<new_node->lvl){
            new_node->next_node[lvl] = cur_node->next_node[lvl];
            cur_node->next_node[lvl] = new_node;
        }
        if(lvl==0) return;
        insert_impl(cur_node,new_node,lvl-1);
        return;
    }
    insert_impl(cur_node->next_node[lvl],new_node,lvl);
}
sl_node* insert(long p_val)
{
    sl_node* new_node = create_node();
    new_node->value = p_val;
    insert_impl(head, new_node,max_level-1);
    return new_node;
}
Run Code Online (Sandbox Code Playgroud)

这是查找操作的代码:

sl_node* find_impl(sl_node* cur_node,
        long p_val,
        int lvl)
{
    if(cur_node==nullptr) return nullptr;
    if(cur_node->value==p_val) return …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm performance skip-lists data-structures

22
推荐指数
1
解决办法
1326
查看次数

从C++中的嵌入式LLVM生成二进制代码(共享库)

我正在研究用C++编写的高性能系统.该过程需要能够在运行时理解一些使用为此应用程序开发的简单语言编写的复杂逻辑(规则).我们有两种选择:

  1. 解释逻辑 - 运行嵌入式解释器并生成动态函数调用,当接收数据时,基于解释逻辑处理数据

  2. 将逻辑编译成plugin.so动态共享文件,使用dlopen,dlsym加载插件并在运行时调用逻辑函数

选项2看起来非常有吸引力,因为它将是优化的机器代码,在运行过程中运行速度比嵌入式解释器快得多.

我正在探索的选项是:

    • 编写一个编译方法字符串编译(字符串逻辑,列表和错误,列表和警告)
    • 这里输入逻辑是一个包含用我们的自定义语言编码的逻辑的字符
    • 它生成llvm ir,compile方法的返回值返回ir字符串
    • 写链接方法bool link(string ir,string filename,list&errors,list&warnings)
    • 对于链接方法我搜索llvm文档,但我还没有找到是否有可能写这样的方法

    如果我是正确的,LLVM IR将转换为LLVM字节代码或汇编代码.然后使用LLVM JIT在JIT模式下运行或使用GNU Assembler用于生成本机代码.

    是否有可能在LLVM中找到这样做的功能?如果它是从代码中完成的,而不是使用来自C++的系统命令来调用"as"来生成我的需求的plugin.so文件,那将会更好.

    如果您知道我可以在运行时从我的进程生成共享库本机二进制代码的任何方法,请通知我.

    c++ llvm llvm-ir llvm-c++-api

    13
    推荐指数
    1
    解决办法
    2510
    查看次数

    C++为SIMD设计:使SoA不再是PiTA

    苦乐参半的SoAs

    我最近看到了使用手工编写的SIMD内在函数与SoA(数组结构)表示的乐趣.

    与我之前的AoS(结构阵列)代码相比,速度的改进,至少对于简单的顺序型流媒体操作而言,在加倍到三倍的速度增加时几乎没有什么惊人的.作为奖励,它简化了逻辑,除了减少内存使用外,还排除了那些棘手的水平操作和混乱组件.

    然而,之后有这种苦乐参半的感觉,我意识到他们在代码中使用的是什么PITA,尤其是界面设计.

    中级接口设计

    我经常处理设计中级接口.它们比视频游戏中的级别更高std::vector,但比级别更低Monster.这些对我来说总是一些最笨拙的接口设计和保持稳定,因为它们不足以提供与标准C++容器一样的简单读/写接口.然而,它们不够高级(在界面的入口点缺乏足够的逻辑)来完全隐藏和抽象出底层表示,只提供高级操作.

    我认为中级设计的一个例子是可编程粒子系统API,它希望在某些场景下尽可能高效和可扩展,同时便于休闲场景(例如脚本编写者).这样的设计必须提供粒子访问,除非它将为每个可能的算法提供与可想象的粒子相关的方法,否则它必须在某个地方暴露一些原始的SoA细节,让客户从中受益.

    设计也不一定要求始终写入SoA类型代码.日常使用量越多,对便利性,简单性,生产率的要求仍然不高.它仅适用于那些罕见的,性能关键的场景,其中底层的SoA表示派上用场.

    那么API/lib设计师和大型系统人员如何处理这些需求的平衡呢?

    平衡多种访问模式

    由于SoA消除了任何每个元素的结构,因此当用户nth使用接口的更方便的随机访问部分访问元素时,动态实例化结构/类可能是一个不错的主意吗?也许一个结构包含指向多个SoA数组的第n个条目的指针/引用以进行可变访问?

    此外,如果更常见的使用模式是更多随机访问标量逻辑而不是顺序访问SIMD向量逻辑,但SIMD部分被触发足以使其更好地仅使用一个数据结构,可能这种混合SoA表示更好地平衡了所有需求?

    struct AoSoA
    {
        ALIGN16 float x[4];
        ALIGN16 float y[4];
        ALIGN16 float z[4];
    };
    ALIGN16 AoSoA elements[n/4];
    
    Run Code Online (Sandbox Code Playgroud)

    我不明白高速缓存行的本质,以便知道这种表示是否值得.我注意到它对顺序SIMD情况没有多大帮助,我们可以将全部资源用于一个庞大的算法,但似乎它可能对需要跨组件或随机访问的大量水平逻辑的情况有帮助标量逻辑情况,系统可能同时执行许多其他操作.

    无论如何,我一般都在寻求深入了解如何有效地设计具有SoA后端表示的中间层数据结构接口作为实现细节,而不会将复杂性转移到客户端,除非他们真的需要它.

    我真的想避免强迫客户端总是在每个使用界面的地方编写SoA类型的代码,除非他们确实需要这种效率,我很好奇如何平衡那些更多的日常随机访问标量使用场景与利用SoA表示的罕见但不太常见的场景.

    c++ architecture optimization simd

    10
    推荐指数
    1
    解决办法
    797
    查看次数

    适用于应用程序级集合的体系结构

    鉴于应用程序范围内的对象集合以及许多需要频繁访问这些对象的无关类,提供所述访问的最佳方法是什么?

    例:

    // Object A, stored in collections, used to do useful things
    class A
    {
      ...
    public:
      QString property(const QString& propertyName) {return m_properties.value(propertyName);}
    
    protected:
      QHash<QString,QString> m_properties;
    }
    
    // Collection class, contains methods to:
    // - Access members of collections
    // - Add/Remove members from collection
    class GlobalCollection
    {
    public:
      // Accessors to collection/collection members
      static A* getAs() {return aHash;}
      static QHash<QString,A*> getAByKey(const QString& key) {return aHash.value(key);}
      static QList<A*> getAsMatchingCriteria(const QString& property, const QString& value)
      {
        QHash<A*> subsetOfA;
    
        foreach(A* pA, …
    Run Code Online (Sandbox Code Playgroud)

    c++ architecture refactoring design-patterns legacy-code

    7
    推荐指数
    1
    解决办法
    94
    查看次数

    SIMD内在函数和持久变量/状态

    我希望这不会成为一个非常愚蠢的问题我稍后会感到尴尬,但我总是对SIMD内在函数感到困惑,以至于我发现汇编代码比内在函数更容易合理化.

    所以我的主要问题是使用SIMD内部数据类型__m256.只是为了跳到这一点,我的问题是做这样的事情:

    class PersistentObject
    {
         ...
    private:
         std::vector<__m256, AlignedAlloc<__m256, 32>> data;
    };
    
    Run Code Online (Sandbox Code Playgroud)

    在生成最有效的代码时,它是否可以接受,是否会使编译器绊倒?这就是我现在困惑的部分.我处于缺乏经验的水平,当我有一个热点并且已经筋疲力尽所有其他直接选择时,我给SIMD内在函数一个镜头,并且如果它们不能提高性能,我总是希望退出我的更改(并且我已经退出这么多与SIMD相关的变化).

    但是这个关于存储SIMD内部类型的问题和困惑一直让我意识到我并不真正理解这些内在函数如何在基本编译器级别上工作.我的想法想要__m256像一个抽象的YMM寄存器(尚未分配).当我看到加载和存储指令时,它开始与我点击.我认为它们是编译器执行其寄存器分配的提示.

    我以前是没有把更多的想进入这个不是,因为我一直使用SIMD类型的临时办法:_mm256_load_ps__m256,做一些操作,结果存储回32位SPFP 256位对齐排列float[8].我想到__m256像YMM寄存器一样.

    摘要YMM注册?

    但是最近我正在实现一个数据结构,试图围绕SIMD处理(一个简单的代表SoA方式的一组向量),这里如果我可以主要工作__m256而不经常从浮点数组加载而变得方便之后将结果存回.在一些快速测试中,MSVC至少似乎发出了将我的内在函数映射到汇编的适当指令(以及当我从向量中访问数据时正确对齐的加载和存储).但这打破了我__m256作为抽象YMM寄存器思考的概念模型,因为存储这些东西会持续地暗示更像常规变量的东西,但在那时,负载/运动和存储是什么?

    所以我对我在脑海中构建的关于如何思考所有这些内容的概念模型略微喋喋不休,我的希望是,也许经验丰富的人可以立即认识到我正在考虑这些东西的方式被破坏了什么我调查我脑子的尤里卡回答.我希望这个问题不是太愚蠢(我有一种不安的感觉,但是我试图在其他地方发现答案,但仍然发现自己很困惑).所以最终,是否可以永久地直接存储这些数据类型(这意味着我们在不使用它已经从YMM寄存器溢出之后的某个时刻重新加载内存_mm_load*),如果是这样,我的概念模型有什么问题?

    如果这是一个如此愚蠢的问题,请道歉!这个东西我耳朵后面真的很湿.

    更多细节

    非常感谢您迄今为止提供的有用评论!我想我应该分享更多细节,以使我的问题不那么模糊.基本上我正在尝试创建一个数据结构,它只是以SoA形式存储的向量集合:

    xxxxxxxx....
    yyyyyyyy....
    zzzzzzzz....
    
    Run Code Online (Sandbox Code Playgroud)

    ...主要是为了用于热点,其中关键循环具有顺序访问模式.但与此同时,非关键执行路径可能想要以AoS形式(x/y/z)随机访问第5个3向量,此时我们不可避免地进行标量访问(如果不是这样的话,那就非常好了)如此高效,因为它们不是关键路径).

    在这个特例中,我发现从实现的角度来看,只是持久存储和使用__m256而不是更方便float*.这将阻止我洒了很多的垂直糊涂的代码_mm_loads*,并_mm_stores*在此情况下(无论是在关键的执行和大部分代码的换算)SIMD内部函数实现,因为通常情况下.但是我不确定这是否只是保留__m256短暂的临时数据,一些函数本地,将一些浮点数加载到__m256,执行某些操作,并按照我通常所做的那样存储结果过去.它会更加方便,但我有点担心这种方便的实现方式可能会阻塞一些优化器(尽管我还没有发现它的情况).如果他们没有绊倒优化器,那么我一直在思考这些数据类型的方式有点过时了.

    所以在这种情况下,就好像做完这些东西并且我们的优化器一直处理得非常好,然后我很困惑,因为我正在思考这些东西的方式,并认为我们需要那些明确的_mm_load_mm_store短暂的上下文(函数的本地,即)帮助我们的优化器是错的!而这种情况让我感到不安,因为我觉得这应该没问题!:-D

    答案

    来自Mysticial的一些评论确实对我来说很有帮助,并且帮助我修复了我的大脑,并且给了我一些保证,我想做的事情是正确的.它是以评论的形式而不是答案的形式给出的,所以我会在这里引用它,以防任何人碰巧遇到类似的混淆.

    如果它有帮助,我有大约200k LOC写得完全像这样.IOW,我将SIMD类型视为一等公民.没关系.编译器处理它们与任何其他基本类型没有区别.所以没有问题.

    优化者并不那么脆弱.他们确实在C/C++标准的合理解释中保持正确性.除非您需要特殊的(未对齐,非时间,蒙版等),否则不需要加载/存储内在函数.

    也就是说,请随时写下自己的答案.更多信息更好!我真的希望能够更有信心地改进对如何编写SIMD代码的基本理解,因为我正处于对所有事情犹豫不决的阶段,并且仍然在猜测自己.

    反思

    再次感谢大家!我现在感觉非常清楚,并且对设计围绕SIMD构建的代码更有信心.出于某种原因,我对SIMD内在函数的优化器非常怀疑,认为我必须以尽可能最低级别的方式编写代码,并在有限的函数范围内尽可能将这些加载和存储作为本地.我认为我的一些迷信来自于几乎几十年前编写的SIMD内在函数最初针对较旧的编译器,也许当时优化器可能需要更多的帮助,或者我可能一直都是非理性的迷信.我看着它有点像80年代人们如何看待C编译器,在register这里和那里提出类似的提示.

    有了SIMD,我总是有非常喜欢的结果,并且有一种趋势,尽管每次在蓝色的月亮里一次又一次地使用它,总是觉得自己像个初学者,也许只是因为混合的成功让我不愿意使用它严重拖延了我的学习过程.最近我想纠正这个问题,我非常感谢所有的帮助!

    c++ sse simd intrinsics avx

    7
    推荐指数
    1
    解决办法
    358
    查看次数

    Clojure - 是否可以在doseq语句中增加变量?

    我试图迭代给定目录中的文件列表,并将一个递增变量i = {1,2,3 .....}添加到它们的名称中.

    这是我用于迭代文件和更改每个文件名称的代码:

    (defn addCounterToExtIn [d]
      (def i 0)
      (doseq [f (.listFiles (file d)) ] ; make a sequence of all files in d
        (if (and (not (.isDirectory f)) ; if file is not a directry and
                 (= '(\. \i \n) (take-last 3 (.getName f))) ) ; if it ends with .in
          (fs/rename f (str d '/ i (.getName f)))))) ; add i to start of its name
    
    Run Code Online (Sandbox Code Playgroud)

    我不知道我怎么可以增加idoseq通过每个文件进行迭代.或者,是否有更好的循环用于实现所需的结果?

    clojure

    3
    推荐指数
    1
    解决办法
    845
    查看次数

    从Python调用C Math函数的高效解决方案

    我听说过从Python代码调用C函数的不同方法,比如ctypes,cython,swig,Boost.python等.当然,每个方法都有优缺点.我的问题是关于效率.我需要从Python调用C数值函数.这种C函数的典型示例是:

    double f(double x){
      return sin(x)+cos(x)-pow(2,x) + x*x;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    调用需要在一次运行中迭代2000-200000次.

    在这样的背景下,C->Python我应该使用哪种变压器?

    c python performance swig ctypes

    3
    推荐指数
    1
    解决办法
    194
    查看次数