首页 \ 问答 \ 访问者在访问者模式中遍历对象结构时累积状态的好处以及访问者如何实现这一点?(Benefits of accumulating state during traversal of an object structure by a visitor in a visitor pattern and how can the visitor achieve this?)

访问者在访问者模式中遍历对象结构时累积状态的好处以及访问者如何实现这一点?(Benefits of accumulating state during traversal of an object structure by a visitor in a visitor pattern and how can the visitor achieve this?)

Gof关于设计模式访客模式章节:

积累状态 。 访问者可以在访问对象结构中的每个元素时累积状态。没有访问者,此状态将作为额外参数传递给执行遍历的操作,或者它们可能显示为全局变量。

作者在这里积累状态是什么意思, 累积状态如何帮助? 请举例说明在遍历过程中累积状态是有帮助的。


From the Visitor pattern chapter of Gof book on Design patterns :

Accumulating state. Visitors can accumulate state as they visit each element in the object structure.Without a visitor,this state would be passed as extra arguments to the operations that perform the traversal,or they might appear as global variables.

What do the authors mean by accumulating state here and how does accumulating state help ? Please give a practical example where accumulating state during the traversal process is helpful.


原文:https://stackoverflow.com/questions/14605350
更新时间:2023-06-16 08:06

最满意答案

首先,这不是“NEON”。 这是内在的。 使用clang或gcc下的内在函数来获得良好的NEON性能几乎是不可能的。 如果你认为你需要内在函数,你应该手工编写汇编器。

vDSP不比NEON“更优化”。 iOS上的vDSP使用NEON处理器。 vDSP对NEON的使用比使用NEON要好得多。

我还没有挖掘出你的内在代码,但最可能的(事实上几乎肯定是)麻烦的原因是你正在创建等待状态。 在汇编程序中编写(内部函数只是用焊接手套书写的汇编程序),与C中写入内容无关。您不会循环。 你不会比较相同的。 你需要一种新的思维方式。 在汇编中,您可以一次执行多个任务(因为您有不同的逻辑单元),但是您绝对必须按照所有这些东西都可以并行运行的方式进行安排。 良好的装配保证了所有这些管道的完整。 如果你可以阅读你的代码,它非常合理,它可能是垃圾汇编代码。 如果你从不重复自己,那可能是废话汇编代码。 你需要仔细考虑什么是进入什么登记,以及有多少次循环,直到你被允许阅读。

如果它像音译C一样简单,那么编译器会为你做到这一点。 当你说“我要在NEON中写这篇文章”时,你会说“我认为我可以编写比编译器更好的NEON”,因为编译器也使用它。 也就是说,通常可以编写比编译器更好的NEON(特别是gcc和clang)。

如果你准备好潜入这个世界(这是一个非常酷的世界),你有一些阅读。 以下是我推荐的一些地方:

所有这些 ......始终始终始于重新考虑你的算法。 通常,答案不是如何让你的循环快速计算,而是如何经常调用循环。


First, this is not "NEON" per-se. This is intrinsics. It is almost impossible to get good NEON performance using intrinsics under clang or gcc. If you think you need intrinsics, you should hand-write the assembler.

vDSP is not "better optimized" than NEON. vDSP on iOS uses the NEON processor. vDSP's use of the NEON is much better optimized than your use of the NEON.

I haven't dug through your intrinsics code yet, but the most likely (in fact almost certain) cause of trouble is that you're creating wait states. Writing in assembler (and intrinsics are just assembler written with welding gloves on), is nothing like writing in C. You don't loop the same. You don't compare the same. You need a new way of thinking. In assembly you can do more than one thing at a time (because you have different logic units), but you absolutely have to schedule things in such a way that all those things can run in parallel. Good assembly keeps all those pipelines full. If you can read your code and it makes perfect sense, it's probably crap assembly code. If you never repeat yourself, it's probably crap assembly code. You need to carefully consider what is going into what register and at how many cycles there are until you're allowed to read it.

If it were as easy as transliterating C, then the compiler would do that for you. The moment you say "I'm going to write this in NEON" you're saying "I think I can write better NEON than the compiler," because the compiler uses it too. That said, it often is possible to write better NEON than the compiler (particularly gcc and clang).

If you're ready to go diving into that world (and it's a pretty cool world), you have some reading ahead of you. Here's some places I recommend:

ALL THAT SAID... Always always always start by reconsidering your algorithm. Often the answer is not how to make your loop calculate quickly, it's how to not call the loop so often.

相关问答

更多
  • Android NDK中的以下文件中有相关文档:docs / CPU-ARCH-ABIS.html和docs / CPU-ARM-NEON.html。 基本上你想放 APP_ABI := armeabi armeabi-v7a 生成两个共享库,一个没有(针对ARMv5TE),另一个有VFP支持(针对ARMv7)。 要使用NEON支持构建.c / .cpp文件,请在Android.mk文件中将.neon后缀添加到filename(例如:file.cpp.neon)。 或者要构建启用了NEON的所有文件,将其 ...
  • 不要使用d8-d15。 在使用前必须将它们保存在堆叠中。 之后恢复。 编译器会把这些指令放在这里,浪费宝贵的周期。 在Jtr之前加载J。 Jtr预计在比管道晚的流水线阶段。 使用VLDMIA / VSTMIA代替VLD / VST。 VLDMIA / VSTMIA速度更快,并且在流水线方面具有优势。 使用矢量矢量乘法而不是矢量标量乘法。 如果你创建一个循环版本,把pld放在开始处并展开循环,以便每次循环读取每个指针的64字节。 除了我上面提到的那些缺陷 - 这对于NEON来说是新的典型 - 你的方法非常好。 ...
  • 大概。 我对SSE不熟悉,但你可以强迫许多SSE模式表现得像NEON。 这取决于您的编译器和可用库,但请参阅一些Visual Studio FP单元控制功能 。 这可能足以满足您的要求。 此外,您可以使用arm_neon.h标头来确保使用类似的内在函数来完成类似的操作。 最后,如果您真的需要在这些边界条件下实现这种精度,那么您将需要一个好的测试套件来验证您是否按预期实现了结果。 最后,即使使用纯粹的“C”代码(通常符合IEEE-754),并且像其他评论者提到的那样在ARM上使用VFP,您将获得不同的结果,因 ...
  • 霓虹灯“减半添加”操作vhadd工作原理是这样的: A = (B + C) >> 1 而上证所平均内在_mm_avg_epu8这样做: A = (B + C + 1) >> 1 换句话说,Neon用“减半”操作做了截断平均值,而SSE正确地将结果舍入。 幸运的是,有一条Neon指令,其轮回方式与SSE的_mm_avg_epu8相同 - 称为vrhadd - Vector Rounding Halving Add。 The Neon "halving add" operation vhadd works ...
  • 首先,这不是“NEON”。 这是内在的。 使用clang或gcc下的内在函数来获得良好的NEON性能几乎是不可能的。 如果你认为你需要内在函数,你应该手工编写汇编器。 vDSP不比NEON“更优化”。 iOS上的vDSP使用NEON处理器。 vDSP对NEON的使用比使用NEON要好得多。 我还没有挖掘出你的内在代码,但最可能的(事实上几乎肯定是)麻烦的原因是你正在创建等待状态。 在汇编程序中编写(内部函数只是用焊接手套书写的汇编程序),与C中写入内容无关。您不会循环。 你不会比较相同的。 你需要一种新的思 ...
  • 它是llvm-clang的bug或优化。 armcc或gcc会产生你期望的vmla,但如果你阅读了Cortex-A系列程序员指南v3 ,它会说: 20.2.3调度 在某些情况下,可能存在相当大的延迟,特别是VMLA乘法累加(整数为5个周期;浮点数为7个周期)。 应优化使用这些指令的代码,以避免在准备好之前尝试使用结果值,否则会发生停顿。 尽管有几个周期结果延迟,但这些指令完全管道化,因此可以同时运行多个操作。 因此,llvm-clang将vmla分离为multiply并累积以填充管道是有意义的。 It is ...
  • 英特尔有一组有用的宏, neon2sse.h ,它将NEON内在函数转换为SSE。 这使您可以在x86平台上使用NEON内在函数构建和测试C / C ++代码。 Intel has a useful set of macros, neon2sse.h which translate NEON intrinsics to SSE. This enables you to build and test your C/C++ code with NEON intrinsics on an x86 platform ...
  • 我弄清楚问题是什么。 由于在这个C ++项目中编译的一些代码是C代码,我还必须为C设置编译器标志。包括CMakeLists.txt中的以下内容使代码编译: set(NEON_FLAGS "-DENABLE_NEON -mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a15 -Ofast") set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -Wno-format-security ${NEON_FLAGS}") ...
  • 这个问题可能涉及两个不同的因素:1。霓虹灯指令比“常规”ARM指令更快吗? 2.我可以编写比编译器更好的汇编吗? 霓虹灯指令比“常规”ARM指令更快吗? 您的算法仅涉及加载数据并将其存储在其他位置。 在A15上,架构中的加载/存储管道共享用于NEON寄存器和ARM寄存器。 这可能不完整,但过去A8和A9可能存在的任何好处,它们具有不同的加载/存储流水线以及不同的指令发布逻辑,不同的指令重新排序和分支预测功能。 因此,在A15上,当考虑NEON指令与常规ARM指令时,这些考虑不再是一个重要因素。 即使在那时, ...
  • 你在for-statement中的订单错了: 在里面 停止条件 增量 所以,你的循环应该是这样的 for( int i=0; i

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。