如何在现代x86-64 Intel CPU上实现每个周期4个浮点运算(双精度)的理论峰值性能?
据我所知,SSE 需要三个周期,add而mul大多数现代Intel CPU需要五个周期才能完成(参见例如Agner Fog的"指令表").由于流水线操作,add如果算法具有至少三个独立的求和,则每个周期可以获得一个吞吐量.因为打包addpd和标量addsd版本都是如此,并且SSE寄存器可以包含两个,double每个周期的吞吐量可以高达两个触发器.
此外,似乎(虽然我没有看到任何适当的文档)add并且mul可以并行执行,给出每个周期四个触发器的理论最大吞吐量.
但是,我无法使用简单的C/C++程序复制该性能.我最好的尝试导致大约2.7个翻牌/周期.如果有人可以贡献一个简单的C/C++或汇编程序,它可以表现出非常高兴的峰值性能.
我的尝试:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
double stoptime(void) {
struct timeval t;
gettimeofday(&t,NULL);
return (double) t.tv_sec + t.tv_usec/1000000.0;
}
double addmul(double add, double mul, int ops){
// Need to initialise differently otherwise compiler might optimise away
double sum1=0.1, sum2=-0.1, sum3=0.2, sum4=-0.2, sum5=0.0;
double mul1=1.0, mul2= 1.1, mul3=1.2, mul4= 1.3, …Run Code Online (Sandbox Code Playgroud) 我的CPU是Core i3 330M,有2个内核和4个线程.当我/proc/cpuinfo在终端中执行命令cat 时,就好像我有4个CPUS.当我使用OpenMP功能时,get_omp_num_procs()我也得到4.
现在我有一个标准的C++矢量类,我的意思是一个不使用表达式模板的固定大小的双数组类.我仔细并行化了我班级的所有方法,并获得了"预期"的加速.
问题是:在这么简单的情况下,我能猜出预期的加速吗?例如,如果我添加两个没有并行化for循环的向量,我会得到一些时间(使用shell time命令).现在,如果我使用OpenMP,根据内核/线程的数量,我应该将时间除以2或4吗?我强调我只是要求这个特别简单的问题,即数据中没有相互依赖性,一切都是线性的(向量加法).
这是一些代码:
Vector Vector::operator+(const Vector& rhs) const
{
assert(m_size == rhs.m_size);
Vector result(m_size);
#pragma omp parallel for schedule(static)
for (unsigned int i = 0; i < m_size; i++)
result.m_data[i] = m_data[i]+rhs.m_data[i];
return result;
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读过这篇文章:OpenMP线程映射到物理核心.
我希望有人会告诉我更多有关OpenMP如何在这个简单案例中完成工作的信息.我应该说我是并行计算的初学者.
谢谢!
我有一个带有多个For循环的c ++程序; 每个运行大约500万次迭代.是否有任何命令我可以使用g ++来生成.exe将使用多个核心; 即在第一个核心上运行第一个For循环,同时在第二个核心运行第二个For循环?我已经尝试了-O3和-O3 -ftree-vectorize,但在这两种情况下,我的cpu使用率仍然仅在25%左右徘徊.
编辑:这是我的代码,以防万一.我基本上只是制作一个程序来测试我的电脑的速度功能.
#include <iostream>
using namespace std;
#include <math.h>
int main()
{
float *bob = new float[50102133];
float *jim = new float[50102133];
float *joe = new float[50102133];
int i,j,k,l;
//cout << "Starting test...";
for (i=0;i<50102133;i++)
bob[i] = sin(i);
for (j=0;j<50102133;j++)
bob[j] = sin(j*j);
for (k=0;k<50102133;k++)
bob[k] = sin(sqrt(k));
for (l=0;l<50102133;l++)
bob[l] = cos(l*l);
cout << "finished test.";
cout << "the 100120 element is," << bob[1001200];
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我试着写一个如何通过线程类从C程序问题中获得100%CPU使用率的答案.这是我的代码
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
using namespace std;
static int primes = 0;
void prime(int a, int b);
mutex mtx;
int main()
{
unsigned int nthreads = thread::hardware_concurrency();
vector<thread> threads;
int limit = 1000000;
int intrvl = (int) limit / nthreads;
for (int i = 0; i < nthreads; i++)
{
threads.emplace_back(prime, i*intrvl+1, i*intrvl+intrvl);
}
cout << "Number of logical cores: " << nthreads << "\n";
cout << "Calculating number …Run Code Online (Sandbox Code Playgroud) c++ ×4
optimization ×2
architecture ×1
assembly ×1
c ×1
core ×1
cpu ×1
g++ ×1
gcc ×1
openmp ×1