小编jer*_*ble的帖子

特征:编码风格对性能的影响

从我读到的关于Eigen(这里)的内容来看,它似乎operator=()充当了懒惰评估的"障碍" - 例如它导致Eigen停止返回表达式模板并实际执行(优化的)计算,将结果存储到左边的=.

这似乎意味着一个人的"编码风格"对性能产生影响 - 即使用命名变量来存储中间计算的结果可能会对计算的某些部分进行"太早"评估,从而对性能产生负面影响. .

为了验证我的直觉,我写了一个例子并对结果感到惊讶(完整的代码在这里):

using ArrayXf  = Eigen::Array <float, Eigen::Dynamic, Eigen::Dynamic>;
using ArrayXcf = Eigen::Array <std::complex<float>, Eigen::Dynamic, Eigen::Dynamic>;

float test1( const MatrixXcf & mat )
{
    ArrayXcf arr  = mat.array();
    ArrayXcf conj = arr.conjugate();
    ArrayXcf magc = arr * conj;
    ArrayXf  mag  = magc.real();
    return mag.sum();
}

float test2( const MatrixXcf & mat )
{
    return ( mat.array() * mat.array().conjugate() ).real().sum();
}

float test3( const MatrixXcf & mat …
Run Code Online (Sandbox Code Playgroud)

c++ performance readability eigen

37
推荐指数
3
解决办法
3487
查看次数

堆栈大小估计

在多线程嵌入式软件(用C或C++编写)中,必须为线程提供足够的堆栈空间,以使其能够完成其操作而不会溢出.在某些实时嵌入式环境中,正确调整堆栈大小至关重要,因为(至少在我使用过的某些系统中),操作系统不会为您检测到这一点.

通常,在创建线程时(即在pthread_create()等的参数中)指定新线程(除主线程之外)的堆栈大小.通常,这些堆栈大小被硬编码为在最初编写或测试代码时已知良好的值.

但是,对代码的未来更改通常会破坏硬编码堆栈大小所基于的假设,并且在一个重要的日子里,您的线程进入其调用图的更深层分支之一并溢出堆栈 - 从而导致整个系统崩溃或者默默地腐蚀记忆.

在线程中执行的代码在堆栈上声明struct实例的情况下,我个人已经看到了这个问题.当结构体被扩充以容纳额外数据时,堆栈大小相应地膨胀,可能允许堆栈溢出发生.我想这对于已建立的代码库来说可能是一个巨大的问题,其中无法立即知道向结构添加字段的全部效果(太多的线程/函数来查找使用该结构的所有位置).

由于对"堆栈大小"问题的通常响应是"它们不可移植",因此我们假设编译器,操作系统和处理器都是此调查的已知数量.我们也假设没有使用递归,所以我们没有处理"无限递归"场景的可能性.

有哪些可靠的方法来估计线程所需的堆栈大小?我更喜欢离线(静态分析)和自动方法,但欢迎所有想法.

c c++ embedded stack static-analysis

29
推荐指数
3
解决办法
1万
查看次数

printf()使用字符串表"解码器环"调试库

我正在写信,看看你们中是否有人见过或听说过我将要描述的想法的实现.

我有兴趣为嵌入式目标开发一个printf样式的调试库.目标是非常远程的,我和目标之间的通信带宽预算非常紧张,所以我希望能够以非常有效的格式获得调试消息.

通常,调试语句类似于以下内容:

myDebugLibraryPrintf("Inside loop, processing item %d out of %d.\n", i, numItems);
Run Code Online (Sandbox Code Playgroud)

当然,当它被扩展为文本时,打印的字符串类似于"内部循环,处理项目5中的10个\n",总共约42个字节左右.此语句打印出的90%以上的数据是静态的,字面的 - 在编译时已知.当然,在编译时只知道"5"和"10".

我想做的是只能回发那两个整数(8个字节而不是42个).一旦我收到了这些数据,我就会有一些"解码器响铃"让我"重新构建"收到的数据并在我的位置打印出完整的调试信息.

我会自动生成"解码器环"(作为构建过程的一部分),在编译时为每个myDebugLibraryPrintf()语句提供一个唯一的ID,并生成一个将这些唯一ID映射到原始格式字符串的表.然后,任何时候myDebugLibraryPrintf()被调用的目标时,它发送该唯一ID和任何的"%d","%f"等可变参数格式字符串看到的值,但格式字符串本身不会被传送.(我"%s"现在可能只是禁止使用项目...)回到我的位置,我们将有一个程序查找表中的唯一ID,找到相应的格式字符串,并使用它来重建原始调试消息.

我觉得以前可能有人有这个想法,我想社区中的某个人可能会看到类似的东西(或者甚至知道这样做的开源库).

约束:

  • 为了澄清,我在这里处理C/C++,我对printf()的100%完全替换实现不感兴趣 - 像非文字格式字符串,%s(字符串)格式说明符或更高级的东西格式说明符,例如将宽度或精度放在varargs列表中,%*.*d不需要支持.

  • 我希望字符串表作为构建过程的一部分自动生成,因此添加调试不会比添加传统的printf()更多的工作.如果需要超过最小努力量,我项目中的任何人都不会使用它.

  • 在生成字符串表的构建过程中做额外的工作几乎是假定的.幸运的是,我控制了我对使用这个库感兴趣的所有源代码,并且我在构建过程中有很大的灵活性.

谢谢!

c debugging printf string-table

8
推荐指数
1
解决办法
603
查看次数

在C中自动生成函数指针表

我正在寻找一种方法来自动(作为编译/构建过程的一部分)在C中生成函数指针的"表".

具体来说,我想生成一个结构数组,如:

typedef struct {
  void (*p_func)(void);
  char * funcName;
} funcRecord;

/* Automatically generate the lines below: */

extern void func1(void);
extern void func2(void);
/* ... */

funcRecord funcTable[] =
{
  { .p_func = &func1, .funcName = "func1" },
  { .p_func = &func2, .funcName = "func2" }
  /* ... */
};

/* End automatically-generated code. */
Run Code Online (Sandbox Code Playgroud)

...其中func1和func2在其他源文件中定义.

因此,给定一组源文件,每个源文件包含一个不带参数且返回void的函数,如何自动(作为构建过程的一部分)生成一个类似上面包含每个函数的数组从文件?我希望能够添加新文件,并在重新编译时将它们自动插入到表中.

我意识到这可能无法单独使用C语言或预处理器来实现,因此请考虑使用任何常见的*nix风格的工具公平游戏(例如make,perl,shell脚本(如果必须)).

但为什么?

你可能想知道为什么有人想要这样做.我正在为常见的数学例程库创建一个小的测试框架.在这个框架下,将会有许多小的"测试用例",每个测试用例只有几行代码来运行每个数学函数.我希望每个测试用例都作为一个简短的函数存在于自己的源文件中.所有测试用例都将构建到单个可执行文件中,并且可以在调用可执行文件时在命令行上指定要运行的测试用例.main()函数将搜索表,如果找到匹配项,则跳转到测试用例函数.

自动化构建测试用例"目录"的过程可确保测试用例不会被遗漏(例如,因为有人忘记将其添加到表中)并使维护者在添加新测试用例时非常简单未来(例如,只需在正确的目录中创建一个新的源文件).

希望有人在那之前做过类似的事情.谢谢,StackOverflow社区!

c build-process unit-testing function-pointers

5
推荐指数
2
解决办法
2781
查看次数

Linux内核:可以无限期地打开流式DMA映射吗?

关于设备驱动程序编程的许多指南建议流式DMA映射(即由dma_map_single()朋友创建的那些)在尽可能短的时间内保持打开状态,因为它们消耗资源(即,如果平台有一个或者弹跳缓冲区,则为IOMMU映射资源)在需要的时候).

在我的情况下,我正在使用一个支持64位DMA的PCIe设备,因此不需要反弹缓冲区(在这种情况下看起来似乎不需要IOMMU的特殊处理,对吗?).数据来自设备(即它被映射DMA_TO_CPU),当新数据通过中断可用时,设备通知我,此时我dma_sync_for_cpu()在访问刚刚DMA给我的数据之前触发a .

是否有其他原因我不应该无限期地打开映射(当然,直到数据消费者关闭)?

c linux-device-driver dma

5
推荐指数
1
解决办法
275
查看次数