primefaces操作成本

primefaces操作的成本是多less(任何比较和交换或primefaces增加/减less)? 它消耗多less个周期? 它会暂停SMP或NUMA上的其他处理器,还是会阻塞内存访问? 它会在无序的CPU中刷新重sorting缓冲区吗?

什么效果会在caching上?

我对现代stream行的CPU感兴趣:x86,x86_64,PowerPC,SPARC,Itanium。

我查了过去几天的实际数据,一无所获。 但是,我做了一些研究,比较了primefaces操作的成本和caching未命中的成本。

在PentiumPro之前(如文档中所述),x86 LOCK前缀或CAS的成本是内存访问(如caching未命中),+停止其他处理器的内存操作,+与其他处理器的任何争用试图locking总线。 但是,由于PentiumPro,Writeback(即可caching)内存(应用程序所处理的所有内存,除非直接与硬件对话),而不是阻止所有内存操作,只有相关的caching行被阻止(基于上面的链接)。

事实上,中国科学院的情况可能会更复杂,正如本页所解释的那样,没有时间安排,而是由值得信赖的工程师进行深入的描述。

在详细讨论之前,我会说一个LOCK操作花费一个caching未命中+与同一caching行中的其他处理器可能的争用,而CAS +前面的加载(除了互斥体之外,几乎总是需要的CAS 0和1)可能需要两次caching未命中。

他解释说,在单个位置上的加载+ CAS实际上可能会花费两个caching未命中,如Load-Linked / Store-Conditional(请参阅后者)。 他的解释依赖于MESIcaching一致性协议的知识。 它使用4个状态作为caching行:M(odified),E(xclusive),S(hared),I(nvalid)(因此被称为MESI)。 这个情景解释如下:

  • LOAD导致高速caching未命中 – 相关的高速caching行从共享状态的内存中加载(即,其他处理器仍然被允许将该高速caching行保留在内存中;在此状态下不允许更改)。 如果位置在内存中,则跳过此caching未命中。 可能的成本:1caching错过。 (如果高速caching行处于共享,独占或修改状态,即数据在该CPU的L1高速caching中,则跳过)。
  • 该程序计算出新的值来存储,
  • 它运行一个primefacesCAS指令。
    • 必须避免并发修改,因此必须从其他CPU的高速caching中删除高速caching行的副本,以将高速caching行移至独占状态。 可能的成本:1caching错过。 如果它已经是专有的,就不需要,即处于Exclusive或Modified状态。 在这两种状态下,没有其他CPU持有caching行,但处于“独占”状态时尚未被修改(尚)。
    • 在这个通讯之后,这个variables在我们CPU的本地caching中被修改,在这一点上,所有其他CPU都是全局可见的(因为它们的caching与我们的caching是一致的)。 最终会按照通常的algorithm写入主存。
    • 试图读取或修改该variables的其他处理器将首先必须以共享或独占模式获取该caching行,并且这样做将联系该处理器并接收caching行的更新版本。 相反,LOCKed操作只能花费caching未命中(因为caching行将直接以独占状态请求)。

在所有情况下,caching行请求都可能被其他已经修改数据的处理器阻塞。

我做了以下设置分析:testing机器(AMD Athlon64 x2 3800+)被启动,切换到长模式(禁用中断),感兴趣的指令在一个循环中执行,100次迭代展开和1,000个循环。 循环体alignment到16个字节。 在循环之前和之后用rdtsc指令测量时间。 另外,没有任何指令的虚拟循环被执行(每个循环迭代测量2个循环,其余的循环测量14个循环),并且从指令分析时间的结果中减去结果。

测量了以下指示:

  • lock cmpxchg [rsp - 8], rdx ”(都有比较匹配和不匹配),
  • lock xadd [rsp - 8], rdx ”,
  • lock bts qword ptr [rsp - 8], 1

在所有情况下,测量的时间约为310个周期,误差约为+/- 8个周期

这是在同一个(高速caching的)内存上重复执行的值。 有了额外的高速caching未命中,时间是相当高的。 另外,这样做只有两个内核中的一个处于活动状态,所以caching是独占的,不需要caching同步。

为了评估高速caching未命中的locking指令的开销,我在locking的指令之前添加了wbinvld指令,并将wbinvld加上add [rsp - 8], rax wbinvld add [rsp - 8], raxjoin到比较循环中。 在这两种情况下,每个指令对的成本约为80,000个周期! 在locking的情况下,每个指令的时间差约为180个周期。

请注意,这是相互吞吐量,但由于locking操作是序列化操作,所以延迟可能没有区别。

结论:一个locking的操作是沉重的,但一个caching未命中可能会重得多。 另外:locking的操作不会导致caching未命中。 当caching行不是唯一拥有时,它只能导致caching同步stream量。

为了启动机器,我使用了ReactOS项目的FreeLDR的x64版本。 这里是asm源代码:

 #define LOOP_COUNT 1000 #define UNROLLED_COUNT 100 PUBLIC ProfileDummy ProfileDummy: cli // Get current TSC value into r8 rdtsc mov r8, rdx shl r8, 32 or r8, rax mov rcx, LOOP_COUNT jmp looper1 .align 16 looper1: REPEAT UNROLLED_COUNT // nothing, or add something to compare against ENDR dec rcx jnz looper1 // Put new TSC minus old TSC into rax rdtsc shl rdx, 32 or rax, rdx sub rax, r8 ret PUBLIC ProfileFunction ProfileFunction: cli rdtsc mov r8, rdx shl r8, 32 or r8, rax mov rcx, LOOP_COUNT jmp looper2 .align 16 looper2: REPEAT UNROLLED_COUNT // Put here the code you want to profile // make sure it doesn't mess up non-volatiles or r8 lock bts qword ptr [rsp - 8], 1 ENDR dec rcx jnz looper2 rdtsc shl rdx, 32 or rax, rdx sub rax, r8 ret 

在基于总线的SMP上,primefaces前缀LOCK确定(打开)总线信号LOCK# 。 它将禁止总线上的其他cpu /设备使用它。

Ppro&P2 book http://books.google.com/books?id=3gDmyIYvFH4C&pg=PA245&dq=lock+instruction+pentium&lr=&ei=_E61S5ehLI78zQSzrqwI&cd=1#v=onepage&q=lock%20instruction%20pentium&f=false pages 244-246

locking指令正在序列化,同步操作…. /关于无序/lockingRMW /读取 – 修改 – 写入=primefaces本身/指令确保处理器在执行之前执行locking指令之前的所有指令。 /关于尚未刷新的写/它强制执行下一条指令之前将处理器中的所有发布写入刷新到外部存储器。

/关于SMP /信号量处于S状态的高速caching中…对0字节的date发出读取和无效事务(这是相邻CPU中的高速caching行的共享拷贝/)