我的目标是在AFR模式下使用SLI来增加FPS.我的印象是NVIDIA SLI驱动程序会自动智能地将VBO分配给各个GPU.它是否正确?
我有一个代码,其中包含大量顶点/面,由VAO表示,具有三个不同的VBO(顶点,颜色,索引).使用双GPU和SLI不会增加fps.
我用相同的顶点/面复制VAO和VBO,并在两个VAO之间交替glDrawElements调用,希望NVIDIA SLI驱动程序能够聪明地知道一个VAO用于一个GPU,但遗憾的是仍然没有fps增加.有人能让我知道我做错了什么吗?
我还尝试为其中一个VAO注释掉一个glDrawElements调用,它确实显示了双FPS和闪烁的场景与实际场景和黑屏一样.
我试图用一个众所周知的张的方法使用棋盘校准一个摄像机,然后进行捆绑调整,这在Matlab和OpenCV中都可用.有很多经验指导,但从我个人的经验来看,准确性是相当随机的.它有时可能非常好,但有时也非常糟糕.只需将棋盘放在不同的位置,结果实际上可以变化很大.假设目标摄像机是110度水平FOV的直线.
棋盘中的方格数是否会影响准确度?张在他的原始论文中使用8x8而没有真正解释原因.
方块的长度是否会影响精度?张使用17厘米x 17厘米没有真正解释原因.
不同棋盘位置/方向的最佳拍摄数量是多少?张仅使用5张图片.我看到人们建议20到30张带有不同角度的棋盘图像,填满整个视野,向左,向右,向上和向下倾斜,并建议不要将棋盘放置在相似的位置/方向,否则结果将是偏向于那个位置/方向.它是否正确?
目标是找出一个工作流程来获得一致的校准结果.
假设我有一个我要排序的动态数组,我可以做
std::vector<int> v(100);
for (int i = 0; i < 100; i++) v[i] = rand();
std::sort(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)
但对于性能关键代码,初始化开销是不可接受的,更多细节请访问/sf/answers/508836191/
我也可以
int *v = new int[100];
for (int i = 0; i < 100; i++) v[i] = rand();
std::sort(v, v + 100);
Run Code Online (Sandbox Code Playgroud)
但是必须自己管理内存必然会在大型代码库中发生内存泄漏.
所以似乎最可行的方法是
std::unique_ptr<int[]> v(new int[100]);
for (int i = 0; i < 100; i++) v[i] = rand();
std::sort(v, v + 100);
Run Code Online (Sandbox Code Playgroud)
没有初始化开销也不需要担心内存管理,但这会返回一个很长的编译错误.有人能让我知道我做错了什么吗?
我在Ubuntu 14.04,GCC作为编译器.
编辑:更改代码,以便数据尚未排序
我正在尝试将多个目标分组为一个目标,以便下游用户只需要链接到该单个目标。下游用户不需要查找所有目标,并且上游库中的所有功能都可以通过链接到该目标来使用。请参阅下面我失败的尝试的 CMakeLists。
cmake_minimum_required(VERSION 3.11)
project(modules)
# 10 libraries with actually functionality
add_subdirectory(mylib1)
add_subdirectory(mylib2)
...
add_subdirectory(mylib10)
# failed attempt to create a single library that links to the above 10
add_library(myliball)
target_link_libraries(myliball mylib1 mylib2 ... mylib10)
install(TARGETS myliball
EXPORT ${CMAKE_PROJECT_NAME}Targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
export(TARGETS myliball
APPEND FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
Run Code Online (Sandbox Code Playgroud)
当我运行 cmake 时它显示此错误
No SOURCES given to target: myliball
Run Code Online (Sandbox Code Playgroud)
我也许可以为 myliball 创建一个空类来解决这个问题,但这似乎很混乱。有一个更好的方法吗?
我正在使用 Eigen::SparseMatrix,但我无法理解innerIndexPtr和 的含义outerIndexPtr。官方页面的解释对我来说非常模糊。直观上,我认为innerIndexPtr是非零元素的行索引,outerIndexPtr是非零元素的列索引,但显然情况并非如此。请看下面的例子,
std::vector<Eigen::Triplet<double>> triplet;
triplet.emplace_back(0, 0, 10);
triplet.emplace_back(2, 0, 11);
Eigen::SparseMatrix<double> A(3, 3);
A.setFromTriplets(triplet.begin(), triplet.end());
std::cout << A.innerIndexPtr()[0] << std::endl; // prints 0
std::cout << A.innerIndexPtr()[1] << std::endl; // prints 2
std::cout << std::endl;
std::cout << A.outerIndexPtr()[0] << std::endl; // prints 0
std::cout << A.outerIndexPtr()[1] << std::endl; // prints 2, but I thought it should print 0
std::cout << std::endl;
std::cout << A.valuePtr()[0] << std::endl; // prints 10
std::cout …Run Code Online (Sandbox Code Playgroud) 让我们说光标位于N行,我们用yy将它拉出来,我们想要粘贴到光标下面的20行.是否可以在不将光标向下移动的情况下这样做,如20j,p,20k?尝试20p,但它只粘贴了20个重复的行.一些谷歌搜索后我找不到解决方案,我不能是唯一需要这个解决方案的人.
我想要做的是猛拉(yy)当前行,粘贴到下面20行,向下走一行(j),猛拉(yy)当前行,粘贴到33行以下,向下走一行(j),猛拉(yy)当前行,粘贴到下面的41行,向下一行(j),冲洗并重复
我在Ubuntu 14.04,g ++ 4.9.3.下面的代码
std::vector<std::array<int, 3>> a;
a.push_back({2, 3, 1});
a.push_back({1, 3, 4});
a.push_back({3, 1, 2});
auto it = std::find(a.begin(), a.end(), {2, 3, 1});
Run Code Online (Sandbox Code Playgroud)
返回错误
couldn't deduce template parameter ‘_Tp’
std::find(a.begin(), a.end(), {2, 3, 1});
^
Run Code Online (Sandbox Code Playgroud)
经过几次谷歌搜索会议后,我想出了一个更精细的方法来使用std :: find_if和lambda函数来解决这个问题,但为什么这段代码不起作用呢?
我遇到了编译错误,将bool向量复制到cuda内存将失败
bool *gpu;
cudaMalloc(reinterpret_cast<void **>(&gpu), 100);
std::vector<bool> cpu(100);
for(int i=0;i<100;i++){
cpu[i]=true;
}
cudaMemcpy(gpu, cpu.data(), 100*sizeof(bool), cudaMemcpyHostToDevice);
Run Code Online (Sandbox Code Playgroud)
它回来了
error: invalid use of void expression cudaMemcpyHostToDevice);
Run Code Online (Sandbox Code Playgroud)
但是带有float向量的相同代码将被编译.
float *gpu;
cudaMalloc(reinterpret_cast<void **>(&gpu), 100);
std::vector<float> cpu(100);
for(int i=0;i<100;i++){
cpu[i]=i;
}
cudaMemcpy(gpu, cpu.data(), 100*sizeof(float), cudaMemcpyHostToDevice);
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
假设我有一个看起来像的功能
void *func(){
int *a = new int;
*a = 1;
void *b = a;
return b;
}
Run Code Online (Sandbox Code Playgroud)
在我的主要功能中我可以使用它
int *test = reinterpret_cast<int *>(func());
std::cout << test[0] << std::endl;
delete test;
Run Code Online (Sandbox Code Playgroud)
它会打印出正确的结果.让我们说我想使用unique_ptr为我的功能,所以它成为
std::unique_ptr<void> func(){
std::unique_ptr<int> a(new int);
*a = 1;
std::unique_ptr<void> b = a; // does not compile
return b;
}
Run Code Online (Sandbox Code Playgroud)
它会抛出编译错误
error: conversion from ‘std::unique_ptr<int>’ to non-scalar type ‘std::unique_ptr<void>’ requested
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我该怎么做才能使unique_ptr工作?
假设我的 Add.h 位于命名空间内,并且我将其设为 AddTest 的友元,以便它可以访问 AddTwoNumber。
namespace mynamespace
{
class Add
{
friend class AddTest;
public:
Add(){};
~Add(){};
private:
int AddTwoNumber(const int a, const int b){return a+b};
};
}
Run Code Online (Sandbox Code Playgroud)
我的 AddTest.h 是
#include "Add.h"
#include "gtest/gtest.h"
class AddTest : public ::testing::Test
{
protected:
AddTest(){};
virtual ~AddTest(){};
virtual void SetUp()
{
mynamespace::Add addobj;
result = addobj.AddTwoNumber(2, 3);
};
virtual void TearDown(){};
int result;
};
Run Code Online (Sandbox Code Playgroud)
但是,它返回错误,因为 AddTwoNumber 是私有的。如果我在 Add.h 中取出“mynamespace”,该代码就可以工作。有没有办法保留命名空间但仍允许 AddTest 访问 Add.h 中的私有方法?
我在 Ubuntu 16.04 上。假设我得到了一个随机的 libtestcuda.so 文件,无论如何我可以检查编译库的 CUDA 计算兼容性吗?
我试过了
ll libtestcuda.so
Run Code Online (Sandbox Code Playgroud)
它没有显示太多。
我想知道这一点,因为如果我编译我的代码
-gencode arch=compute_30,code=sm_30;
Run Code Online (Sandbox Code Playgroud)
它在我编写的一个小型 cuda 程序上编译并运行良好,但是当我在我的 GPU 上运行 deviceQuery 时,它实际上显示了 CUDA 计算兼容性 3.5,所以我很想知道这段代码是否会在 3.0 或 3.5 架构中执行。
如果我编译并运行它
-gencode arch=compute_20,code=sm_20;
Run Code Online (Sandbox Code Playgroud)
或者
-gencode arch=compute_50,code=sm_50;
Run Code Online (Sandbox Code Playgroud)
它按预期失败。
如果我编译并运行它
-gencode arch=compute_35,code=sm_35;
Run Code Online (Sandbox Code Playgroud)
它按预期运行良好。
假设我想要使用的遗留库中有一个函数需要函数指针作为输入
void LegacyFunction(int* (*func)(float, float), int a, float b);
Run Code Online (Sandbox Code Playgroud)
但问题是它期望函数的返回值是一个int原始指针而不是int unique_ptr,这意味着如果我的函数看起来像我只能编译它
int* MyFunc(float a, float b);
Run Code Online (Sandbox Code Playgroud)
换句话说,如果我将MyFunc修改为
std::unique_ptr<int> MyFunc(float a, float b);
Run Code Online (Sandbox Code Playgroud)
并将其传递给遗留库函数,如
LegacyFunction(MyFunc, 1, 2.0f);
Run Code Online (Sandbox Code Playgroud)
会有编译错误.我知道如果该函数采用通常的int指针,可以使用get()像这样的函数进行一些解决方法
std::unique_ptr<int> a;
LegacyFunctionRawPointer(a.get(), 1, 2.0f);
Run Code Online (Sandbox Code Playgroud)
函数指针输入是否有类似的解决方法?如果我必须用原始指针替换MyFunc的unique_ptr,那将是一个讽刺.
下面是使用调试变量的示例
class A{
public:
A(bool debug):m_debug(debug){};
~A(){};
void Test(){
for(int i=0;i<1000000;i++){
// do something
if(m_debug) print();
}
}
void print(){
std::cout << "something" << std::endl;
}
private:
bool m_debug;
};
Run Code Online (Sandbox Code Playgroud)
下面是使用调试宏预处理器的示例
#include "Preprocessor.h"
class A{
public:
void Test(){
for(int i=0;i<1000000;i++){
// do something
#ifdef DEBUG
print();
#endif
}
}
void print(){
std::cout << "something" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
在Preprocessor.h中简单
#define DEBUG
Run Code Online (Sandbox Code Playgroud)
使用调试变量的好处是类对全局预处理器头的依赖性较小.关于宏方法的好处是,如果在运行时执行语句,则减少1000000,这对于每个fps计数时的图形应用程序来说可能是至关重要的.什么被认为是更好的方法?
c++ ×9
c++11 ×4
cuda ×2
calibration ×1
cmake ×1
debugging ×1
eigen ×1
eigen3 ×1
fbo ×1
frame-rate ×1
friend ×1
googletest ×1
gpu ×1
heap-memory ×1
macros ×1
namespaces ×1
nvidia ×1
opencv ×1
opengl ×1
pointers ×1
sli ×1
unique-ptr ×1
vector ×1
vim ×1