我有一个简单的MPI代码,打印出进程级别,编译并与英特尔编译器和MPI库链接.然后我以交互方式在集群的主节点上运行它:mpiexec -n 50 ./a.out该节点只有12个内核和24个逻辑处理器(超线程?).但我可以用50甚至更多的进程来运行它.什么原因?
我正在观察最后几个英特尔微体系结构(Nehalem/SB/IB和Haswell).我正在尝试解决发生数据请求时发生的事情(在相当简化的级别).到目前为止,我有这个粗略的想法:
在这一点上,可能会发生两件事,一件未命中或一件事:
如果它命中了CPU,那么按顺序尝试L1D/L2/L3缓存,页表和主内存/硬盘?
如果它错过了 - CPU请求(集成内存控制器?)请求检查RAM中保存的页表(我是否在那里得到了IMC的角色?).
如果有人可以编辑/提供一组项目符号,这些项目提供CPU对执行引擎数据请求所做的基本"概述",包括
非常感谢.我找到了一些有用的图片:
但他们并没有真正区分TLB和缓存之间的相互作用.
更新:改变了上述内容,因为我认为我现在明白了.TLB只从虚拟地址获取物理地址.如果错过了 - 我们遇到了麻烦,需要检查页面表.如果有一个命中,我们只需从L1D缓存开始向下遍历内存层次结构.
我有一个Intel Core i5-2450m(2个物理处理器和4个逻辑处理器),我想找到一种方法来计算AMD和Intel CPU上的逻辑和物理内核.但是,经过一些搜索,我注意到了一些奇怪 我的代码给了我16而不是返回4个逻辑单元.
static int8_t LogicalProcCount(void)
{
if ( !Hyperthreading )
return 1;
uint32_t unused, ebx;
CPUID(1, unused, ebx, unused, unused);
return (int8_t) ( (ebx >> 16 ) & 0xFF );
}
Run Code Online (Sandbox Code Playgroud) 英特尔x86_64处理器不仅是流水线架构,还是超标量?
流水线操作 - 这两个序列并行执行(同一时钟中相同流水线单元的不同阶段,例如4个阶段的ADD):
超标量 - 这两个序列并行执行(两个指令可以在同一时钟中启动到不同的流水线单元,例如ADD和MUL):
在阅读英特尔64和IA-32架构软件开发人员手册时,LEA指令的操作部分(加载有效地址)使用了一个EffectiveAddress(SRC)
在其他任何地方都没有定义的计算.
有效地址的定义是什么,EffectiveAddress(SRC)
做什么?
在x86-64中,如果使用以下汇编代码:
MOV RAX, (memory address)
JMP RAX
Run Code Online (Sandbox Code Playgroud)
管道在执行分支之前是否停止(等待MOV完成RAX),还是像条件分支一样刷新管道?
有没有人知道如何设置perf_event_attr
可以触发PMU监控多个(类型)事件的结构perf_event_open()
?
比如perf record -e cycles,faults ls
,它有两种不同的事件类型(PERF_TYPE_HARDWARE和PERF_TYPE_SOFTWARE),但在perf_event_open的联机帮助页上的示例中,perf_event_attr.type
只能分配单个值.
任何建议将不胜感激,谢谢!
20170208更新 感谢@gudok指点我的方向,但结果似乎有些异常.演示程序如下(用于测量整个系统的CPU周期和缓存未命中):
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <asm/unistd.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>
#include <time.h>
struct read_format {
uint64_t nr;
struct {
uint64_t value;
uint64_t id;
} values[];
};
int main(int argc, char* argv[]) {
struct perf_event_attr pea;
int fd1, fd2;
uint64_t id1, id2;
uint64_t val1, …
Run Code Online (Sandbox Code Playgroud) 我在SSE2和AVX中实现了4x4矩阵逆.两者都比普通实现更快.但是如果启用AVX(-mavx),则SSE2实现比手动AVX实现运行得更快.似乎编译器使我的SSE2实现与AVX更友好:(
在我的AVX实现中,乘法次数减少,添加次数减少......所以我希望AVX可以比SSE更快.也许有些像说明资讯_mm256_permute2f128_ps
,_mm256_permutevar_ps/_mm256_permute_ps
使得AVX慢?我不是要将SSE/XMM寄存器加载到AVX/YMM寄存器.
如何使我的AVX实现比SSE更快?
我的CPU:Intel(R)Core(TM)i7-3615QM CPU @ 2.30GHz(Ivy Bridge)
Plain with -O3 : 0.045853 secs
SSE2 with -O3 : 0.026021 secs
SSE2 with -O3 -mavx: 0.024336 secs
AVX1 with -O3 -mavx: 0.031798 secs
Updated (See bottom of question) all have -O3 -mavx flags:
AVX1 (reduced div) : 0.027666 secs
AVX1 (using rcp_ps) : 0.023205 secs
SSE2 (using rcp_ps) : 0.021969 secs
Run Code Online (Sandbox Code Playgroud)
初始矩阵:
Matrix (float4x4):
|0.0714 -0.6589 0.7488 2.0000|
|0.9446 0.2857 0.1613 4.0000|
|-0.3202 0.6958 0.6429 6.0000|
|0.0000 …
Run Code Online (Sandbox Code Playgroud) 我的原始数据是一堆c数组(长度为1000000)(无符号)char(8位)。我想将它们加在一起(矢量加法),遵循以下代码中的规则。结果:(无符号)short(16位)的c数组。
我已经阅读了所有SSE和AVX / AVX2,但有一个类似的调用,即多个2个256位寄存器。前4个32位将相乘,每对32位的结果是一个64位,将适合256个寄存器。(_mm256_mul_epi32,_mm256_mul_epu32)
https://www.codeproject.com/Articles/874396/Crunching-Numbers-with-AVX-and-AVX
样例代码:
static inline void adder(uint16_t *canvas, uint8_t *addon, uint64_t count)
{
for (uint64_t i=0; i<count; i++)
canvas[i] += static_cast<uint16_t>(addon[i]);
}
Run Code Online (Sandbox Code Playgroud)
谢谢
我想将线程ping通到两个CPU插槽中的所有内核,并在线程之间写入通信而无需回写DRAM。
如果仅在一个插槽中使用内核,则写回高速缓存对我的吞吐量就可以了,但是对于两个插槽,我想知道是否有更快的速度,例如片上网络或Intel QuickPath Interconnect?
此外,是否有任何简单的方法可以利用这种功能而无需直接编写汇编代码?
参考:https : //software.intel.com/zh-cn/forums/intel-moderncode-for-parallel-architectures/topic/700477