我是TensorFlow的新手.我最近安装了它(Windows CPU版本)并收到以下消息:
成功安装了tensorflow-1.4.0 tensorflow-tensorboard-0.4.0rc2
然后,当我试图跑
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
sess.run(hello)
'Hello, TensorFlow!'
a = tf.constant(10)
b = tf.constant(32)
sess.run(a + b)
42
sess.close()
Run Code Online (Sandbox Code Playgroud)
(我通过https://github.com/tensorflow/tensorflow找到)
我收到以下消息:
2017-11-02 01:56:21.698935:IC:\ tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137]你的CPU支持这个说明TensorFlow二进制文件未编译使用:AVX AVX2
但是当我跑的时候
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
Run Code Online (Sandbox Code Playgroud)
它运行应该和输出Hello, TensorFlow!
,这表明安装确实成功,但还有其他错误.
你知道问题是什么以及如何解决它?谢谢.
以下代码是否有效以检查CPU是否支持SSE3指令集?
使用该IsProcessorFeaturePresent()
功能显然不适用于Windows XP(请参阅http://msdn.microsoft.com/en-us/library/ms724482(v=vs.85).aspx).
bool CheckSSE3()
{
int CPUInfo[4] = {-1};
//-- Get number of valid info ids
__cpuid(CPUInfo, 0);
int nIds = CPUInfo[0];
//-- Get info for id "1"
if (nIds >= 1)
{
__cpuid(CPUInfo, 1);
bool bSSE3NewInstructions = (CPUInfo[2] & 0x1) || false;
return bSSE3NewInstructions;
}
return false;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试优化一些矩阵计算,我想知道是否有可能在编译时检测SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI [1]是否由编译器?理想情况下,对于GCC和Clang,但我只能管理其中一个.
我不确定它是否可能,也许我将使用自己的宏,但我更愿意检测它并要求用户选择它.
[1] "KCVI"代表骑士角矢量指令优化.像FFTW这样的库检测/利用这些较新的指令优化.
我的C++代码使用SSE,现在我想改进它以支持AVX可用时.所以我检测AVX何时可用并调用使用AVX命令的函数.我使用Win7 SP1 + VS2010 SP1和带AVX的CPU.
要使用AVX,必须包含以下内容:
#include "immintrin.h"
Run Code Online (Sandbox Code Playgroud)
然后你可以使用内在的AVX函数_mm256_mul_ps
,_mm256_add_ps
等等.问题是,默认情况下,VS2010产生的代码工作得非常慢,并显示警告:
警告C4752:发现英特尔(R)高级矢量扩展; 考虑使用/ arch:AVX
似乎VS2010实际上不使用AVX指令,而是模仿它们.我添加/arch:AVX
到编译器选项并获得了良好的结果.但是这个选项告诉编译器尽可能在任何地方使用AVX命令.所以我的代码可能会崩溃在不支持AVX的CPU上!
所以问题是如何使VS2010编译器生成AVX代码,但只有当我直接指定AVX内在函数时.对于它工作的SSE,我只使用SSE内在函数,它产生SSE代码,没有任何编译器选项,如/arch:SSE
.但对于AVX而言,由于某些原因它不起作用.
我对使用Sandy-Bridge和Haswell可以完成每个核心每个循环的触发器感到困惑.据我所知,对于SSE,每个核心每个周期应该为4个触发器,对于AVX/AVX2,每个核心每个周期应该有8个触发器.
这似乎在这里得到验证, 如何实现每个周期4个FLOP的理论最大值? ,这里, Sandy-Bridge CPU规范.
然而,下面的链接似乎表明,Sandy-bridge每个核心每个周期可以执行16个触发器,每个核心每个循环使用Haswell 32个触发器 http://www.extremetech.com/computing/136219-intels-haswell-is-an-前所未有-threat-to-nvidia-amd.
谁可以给我解释一下这个?
编辑:我现在明白为什么我感到困惑.我认为术语FLOP仅指单浮点(SP).我现在看到如何在每个循环中实现理论最大值4 FLOP的测试?实际上是双浮点(DP),因此它们为SSE实现4个DP FLOP /周期,为AVX实现8个DP FLOP /周期.在SP上重做这些测试会很有趣.
我已经使用英特尔的SSE内在函数已经有一段时间了,性能有了很好的提升.因此,我期望AVX内在函数能够进一步加速我的程序.不幸的是,直到现在情况并非如此.可能我犯了一个愚蠢的错误,所以如果有人能帮助我,我将非常感激.
我使用Ubuntu 11.10和g ++ 4.6.1.我编写了我的程序(见下文)
g++ simpleExample.cpp -O3 -march=native -o simpleExample
Run Code Online (Sandbox Code Playgroud)
测试系统配有Intel i7-2600 CPU.
这是代表我的问题的代码.在我的系统上,我得到输出
98.715 ms, b[42] = 0.900038 // Naive
24.457 ms, b[42] = 0.900038 // SSE
24.646 ms, b[42] = 0.900038 // AVX
Run Code Online (Sandbox Code Playgroud)
注意,仅选择计算sqrt(sqrt(sqrt(x)))以确保内存带宽不限制执行速度; 这只是一个例子.
simpleExample.cpp:
#include <immintrin.h>
#include <iostream>
#include <math.h>
#include <sys/time.h>
using namespace std;
// -----------------------------------------------------------------------------
// This function returns the current time, expressed as seconds since the Epoch
// -----------------------------------------------------------------------------
double getCurrentTime(){
struct timeval curr;
struct timezone tz;
gettimeofday(&curr, &tz);
double tmp = …
Run Code Online (Sandbox Code Playgroud) 我已经了解到一些Intel/AMD CPU可以同时进行多次复用并添加SSE/AVX:
每个周期的FLOPS用于沙桥和haswell SSE2/AVX/AVX2.
我想知道如何在代码中做到最好,我也想知道它是如何在CPU内部完成的.我的意思是超标量架构.假设我想做一个很长的总和,如下面的SSE:
//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (e.g. from matrix multiplication)
sum = _mm_set1_ps(0.0f);
a1 = _mm_set1_ps(a[0]);
b1 = _mm_load_ps(&b[0]);
sum = _mm_add_ps(sum, _mm_mul_ps(a1, b1));
a2 = _mm_set1_ps(a[1]);
b2 = _mm_load_ps(&b[4]);
sum = _mm_add_ps(sum, _mm_mul_ps(a2, b2));
a3 = _mm_set1_ps(a[2]);
b3 = _mm_load_ps(&b[8]);
sum = _mm_add_ps(sum, _mm_mul_ps(a3, b3));
...
Run Code Online (Sandbox Code Playgroud)
我的问题是如何将其转换为同时乘法并添加?数据可以依赖吗?我的意思是CPU可以_mm_add_ps(sum, _mm_mul_ps(a1, b1))
同时执行还是在乘法中使用的寄存器和add必须是独立的?
最后,这如何适用于FMA(与Haswell)?是_mm_add_ps(sum, _mm_mul_ps(a1, b1))
自动转换为单个FMA指令还是微操作?
在高级向量扩展(AVX)中,比较指令如_m256_cmp_ps,最后一个参数是比较谓词.谓词的选择压倒了我.它们似乎是类型,排序,信号的三重奏.例如_CMP_LE_OS是'小于或等于,有序,信令.
对于初学者来说,是否存在选择信令或非信令的性能原因,同样,有序或无序的速度比另一个更快?
什么'非信令'甚至意味着什么?我根本无法在文档中找到这个.任何关于何时选择什么的经验法则?
以下是avxintrin.h的谓词选择:
/* Compare */
#define _CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */
#define _CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */
#define _CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */
#define _CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */
#define _CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */
#define _CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */
#define _CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */
#define _CMP_ORD_Q 0x07 /* Ordered (nonsignaling) */
#define _CMP_EQ_UQ 0x08 /* Equal (unordered, non-signaling) */
#define …
Run Code Online (Sandbox Code Playgroud) 是否有用于学习英特尔SSE和AVX指令的优秀C/C++教程或示例?
我在微软MSDN和英特尔网站上发现很少,但从基础知识中理解它会很棒.
我一直试图找出应用程序中的性能问题,并最终将其缩小到一个非常奇怪的问题.如果VZEROUPPER
指令被注释掉,则下面的代码在Skylake CPU(i5-6500)上运行速度慢6倍.我测试了Sandy Bridge和Ivy Bridge CPU,两种版本都以相同的速度运行,有或没有VZEROUPPER
.
现在我VZEROUPPER
对这个代码有了一个相当好的想法,而且我认为当没有VEX编码指令并且没有调用可能包含它们的任何函数时,它对这个代码根本不重要.事实上它不支持其他支持AVX的CPU似乎支持这一点.英特尔®64和IA-32架构优化参考手册中的表11-2也是如此
那么发生了什么?
我留下的唯一理论是,CPU中存在一个错误,它错误地触发了"保存AVX寄存器的上半部分"程序,而不应该这样做.或者其他一些同样奇怪的东西.
这是main.cpp:
#include <immintrin.h>
int slow_function( double i_a, double i_b, double i_c );
int main()
{
/* DAZ and FTZ, does not change anything here. */
_mm_setcsr( _mm_getcsr() | 0x8040 );
/* This instruction fixes performance. */
__asm__ __volatile__ ( "vzeroupper" : : : );
int r = 0;
for( unsigned j = 0; j < 100000000; ++j )
{
r |= slow_function(
0.84445079384884236262,
-6.1000481519580951328, …
Run Code Online (Sandbox Code Playgroud)