小编rmc*_*701的帖子

在Windows中运行时CUDA性能下降

当我在Windows 7中运行我的CUDA应用程序时(相对于Linux),我注意到了性能上的巨大打击.我想我可能知道减速发生的位置:无论出于何种原因,Windows Nvidia驱动程序(版本331.65)在通过运行时API调用时不会立即调度CUDA内核.为了说明这个问题,我描述了mergeSort应用程序(来自CUDA 5.5附带的示例).

首先考虑在Linux中运行时的内核启动时间:

linux_launch

接下来,考虑在Windows中运行时的启动时间:

windows_launch

这篇文章表明问题可能与批量启动内核的Windows驱动程序有关.无论如何我可以禁用这个批处理吗?

我使用的是GTX 690 GPU,Windows 7和Nvidia驱动程序的331.65版本.

linux windows cuda gpu

9
推荐指数
1
解决办法
2662
查看次数

将时序数据馈入有状态LSTM的正确方法?

假设我有一个整数序列:

0,1,2, ..

并希望根据给定的最后3个整数来预测下一个整数,例如:

[0,1,2]->5[3,4,5]->6

假设我像这样设置模型:

batch_size=1
time_steps=3
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, time_steps, 1), stateful=True))
model.add(Dense(1))
Run Code Online (Sandbox Code Playgroud)

据我了解,模型具有以下结构(请原图):

在此处输入图片说明

第一个问题:我的理解正确吗?

请注意,我已经画出了C_{t-1}, h_{t-1}进入图片的先前状态,因为指定时会暴露出来stateful=True。在这个简单的“下一个整数预测”问题中,应通过提供此额外的信息来改善性能(只要先前的状态是由前三个整数产生的)。

这使我想到了一个主要问题: 似乎标准做法(例如,参见此博客文章TimeseriesGenerator keras预处理实用程序)是在训练过程中向模型提供一组交错的输入。

例如:

batch0: [[0, 1, 2]]
batch1: [[1, 2, 3]]
batch2: [[2, 3, 4]]
etc
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑,因为这似乎需要第一Lstm单元的输出(对应于第一时间步长)。看这个图:

从tensorflow docs

stateful:布尔值(默认为False)。如果为True,则批次中索引i的每个样本的最后状态将用作下一个批次中索引i的样本的初始状态。

似乎此“内部”状态不可用,并且所有可用状态都是最终状态。看这个图:

因此,如果我的理解是正确的(显然不是这样),那么在使用时是否不应该将不重叠的样本窗口馈送到模型中stateful=True?例如:

batch0: [[0, 1, 2]]
batch1: [[3, 4, 5]]
batch2: [[6, 7, 8]]
etc
Run Code Online (Sandbox Code Playgroud)

python machine-learning lstm keras tensorflow

7
推荐指数
1
解决办法
226
查看次数

同时使用2个GPU调用cudaMalloc时性能不佳

我有一个应用程序,我在用户系统上的GPU之间分配处理负载.基本上,每个GPU都有CPU线程,当主应用程序线程定期触发时,它会启动GPU处理间隔.

考虑以下图像(使用NVIDIA的CUDA探查器工具生成)作为GPU处理间隔的示例- 此处应用程序使用单个GPU.

在此输入图像描述

正如您所看到的,两个排序操作消耗了大部分GPU处理时间,而我正在使用Thrust库(thrust :: sort_by_key).此外,看起来push :: sort_by_key会在启动实际排序之前调用几个cudaMallocs.

现在考虑应用程序在两个GPU上分散处理负载的相同处理间隔:

在此输入图像描述

在完美的世界中,您可以预期2 GPU处理间隔恰好是单GPU的一半(因为每个GPU的工作量只有一半).正如你所看到的,部分原因并非如此,因为cudaMallocs由于某种争用问题而被同时调用(有时长2-3倍)时似乎需要更长的时间.我不明白为什么会出现这种情况,因为2个GPU的内存分配空间是完全独立的,因此cudaMalloc上不应该有系统范围的锁定 - 每GPU锁定会更合理.

为了证明我的假设问题是同时使用cudaMalloc调用,我创建了一个非常简单的程序,它有两个CPU线程(每个GPU),每个线程多次调用cudaMalloc.我首先运行此程序,以便单独的线程不会同时调用cudaMalloc:

在此输入图像描述

你看,每次分配需要大约175微秒.接下来,我用同时调用cudaMalloc的线程运行程序:

在此输入图像描述

在这里,每个呼叫比前一个案例花了大约538微秒或3倍!毋庸置疑,这极大地减慢了我的应用程序,并且理所当然,只有2个以上的GPU才会使问题变得更糟.

我在Linux和Windows上注意到了这种行为.在Linux上,我使用的是Nvidia驱动程序版本319.60,而在Windows上我使用的是327.23版本.我正在使用CUDA工具包5.5.

可能的原因: 我在这些测试中使用的是GTX 690.这张卡基本上是2 680个GPU,安装在同一个单元中.这是我运行的唯一"多GPU"设置,所以cudaMalloc问题可能与690的2 GPU之间的硬件依赖性有关吗?

parallel-processing cuda gpu-programming multi-gpu thrust

6
推荐指数
2
解决办法
1514
查看次数

Nvidia visual studio Nsight CPU和GPU调试

NVIDIA Nsight Visual Studio Edition似乎无法同时调试CPU(主机代码)和GPU(cuda代码).使用Nsight Eclipse Edition(或cuda-gdb)这非常简单,例如,您可以从主机执行"介入"到CUDA内核.如何使用Visual Studio做同样的事情?

debugging cuda remote-debugging nvidia visual-studio-2012

4
推荐指数
1
解决办法
3381
查看次数

LeakSanitizer:获取运行时泄漏报告?

我继承了一些旧代码,似乎在某处内存泄漏。我的本能是

-faddress=sanitize -fno-omit-frame-pointer
Run Code Online (Sandbox Code Playgroud)

然后让Address Sanitizer的工具系列为我找到泄漏点。但是,我感到非常失望。我希望收到某种运行时错误消息(类似于您不应读写的地址清理程序的错误)。直到程序成功完成之后,泄漏清理器才似乎不进行任何泄漏检查分析。我的问题是,我继承的代码具有多个线程,而并非旨在将所有线程都加入以准备软着陆。

我用一个简单的例子简化了我的问题:

#include <thread>                                           
#include <chrono>                                           
#include <iostream>                                         

bool exit_thread = false;                                   

void threadFunc()                                           
{                                                           
   while(!exit_thread)                                      
   {                                                        
      char* leak = new char[256];                           
      std::this_thread::sleep_for(std::chrono::seconds{1}); 
   }                                                        
}                                                           

int main() {                                                
   std::thread t(threadFunc);                               
   std::cout << "Waiting\n";                                
   std::this_thread::sleep_for(std::chrono::seconds{5});    
   exit_thread = true;                                      
   std::cout << "Exiting\n";                                
   //Without joining here I do not get the leak report.     
   t.join();                                                
   return 0;                                                
}    
Run Code Online (Sandbox Code Playgroud)

我用这个编译

clang++ leaker.cpp -fsanitize=address -fno-omit-frame-pointer -g -O0 -std=c++1y -o leaker      
Run Code Online (Sandbox Code Playgroud)

然后跑

ASAN_OPTIONS='detect_leaks=1' LSAN_OPTIONS='exitcode=55:report_objects=true:log_threads=true:log_pointers=true' ./leaker                                                
Run Code Online (Sandbox Code Playgroud)

(我在这里对“ LSAN_OPTIONS”有点疯狂,因为我在玩耍……没有一个选项可以满足我的要求,但是一旦得知泄漏就退出了)。

如代码中所述,如果我加入线程然后退出程序,则会得到一个漂亮的泄漏报告。否则我什么也得不到。正如你可以成像追踪到遗留代码库10-100线程,并把他们都下去好听点是笨重。

几年前,我记得玩过Visual Leak …

c++ linux multithreading memory-leaks address-sanitizer

4
推荐指数
1
解决办法
1571
查看次数

Microsoft C++ 2012中std :: chrono :: duration :: operator%()的不符合返回值

我正在将一些C++代码移植到Windows(来自Linux/g ++ 4.8.1),我注意到Microsoft的持续时间模数运算符的实现是不正确的.

简单的程序

#include <chrono>
#include <iostream>

using namespace std::chrono;

int main(void)
{
    std::cout << (milliseconds(1050)%seconds(1)).count() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用Microsoft Visual Studio 2012编译时会出现编译错误:

error C2228: left of '.count' must have class/struct/union
Run Code Online (Sandbox Code Playgroud)

标准(http://en.cppreference.com/w/cpp/chrono/duration/operator_arith4)的定义为

template< class Rep1, class Period1, class Rep2, class Period2 >
typename common_type<duration<Rep1,Period1>, duration<Rep2,Period2>>::type
constexpr operator%( const duration<Rep1,Period1>& lhs,
    const duration<Rep2,Period2>& rhs );
Run Code Online (Sandbox Code Playgroud)

即模数运算符返回公共类型的持续时间.Microsoft的实现(http://msdn.microsoft.com/en-us/library/hh874810.aspx)定义为

template<class Rep1, class Period1, class Rep2, class Period2>
constexpr typename common_type<Rep1, Rep2>::type
operator%(
  const duration<Rep1, Period1>& Left,
  const …
Run Code Online (Sandbox Code Playgroud)

c++11 c++-chrono visual-studio-2012

2
推荐指数
1
解决办法
491
查看次数