我有大量的功能,总共大约2.8 GB的目标代码(遗憾的是,没有办法,科学计算......)
当我尝试链接它们时,我得到(预期的)relocation truncated to fit: R_X86_64_32S错误,我希望通过指定编译器标志来避免这些错误-mcmodel=medium.我控制的所有链接的库都使用该-fpic标志进行编译.
仍然,错误仍然存在,我认为我链接到的一些库不是用PIC编译的.
这是错误:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_fini' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x19): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_init' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o: In function `call_gmon_start':
(.text+0x7): relocation truncated to fit: R_X86_64_GOTPCREL against undefined symbol `__gmon_start__'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbegin.o: In function `__do_global_dtors_aux': …Run Code Online (Sandbox Code Playgroud) 我很难STArray通过Google找到的文档和其他howtos /讨论来理解.我在下面有一些更相关的问题.
根据文档,STArrays是
ST monad中的可变盒装和未装箱阵列.
这给了我一个印象,那STArray就是用作在函数之间传递的状态(假设你有一个必须经常更新的向量).
显然,这使用的方式不同:
ST s (STArray s a e)
Run Code Online (Sandbox Code Playgroud)
s这里的州是什么?如果它是在内部使用的,那么为什么这不会被用户隐藏?
这也意味着,如果我们想要将一个STArray s Int Int被传递为状态,那么就可以定义
type StateArray a = Control.Monad.State (ST s (STArray s Int Int)) a
Run Code Online (Sandbox Code Playgroud)
这看起来相当麻烦.
最后,
ST和之间有什么区别State?STArray和IOArray,如果ST和IO是否意味着"内部"使用?谢谢!!
我必须评估包含变量的大量表达式,我正在考虑编写一个小的自定义解释器来保持编译的快速和小.但是我对这个主题没有经验并且有一些问题.
假设我们有一个包含数学表达式和一组有限对象的文件.该文件可能如下所示:
expr[x,y,z] = 2*x*y + x^2 + 28/14*z*(x*y^2 + 15*z) + ...
Run Code Online (Sandbox Code Playgroud)
我想以某种方式解析它,所以我可以通过简单地调用函数来在我的应用程序中以数字方式评估表达式expr(float x, float y, float z).参数的数量不应该是固定的(编辑:每个表达式都有自己的定义,带有适当数量的参数或者接受一个数组),并且应该允许嵌套括号来保持输入文件相当小.
由于表达式都是多项式类型,我可以想到数据结构应该是什么样子,但解析看起来很困难.我已经在SO上找到了一些类似问题的答案,例如使用Lua.
然而,最大的问题是,与直接从自动生成的C代码编译这些表达式相比,创建和调用这些对象时的性能损失是什么.
提前致谢!
编辑:请expr()仅考虑上述示例.我想最好的方法是让模板类的对象保存稀疏数组中变量的系数和幂.
我已经开始使用googletest来实现测试,并在有关参数化测试的文档中偶然发现了这个引用
- 您希望通过各种输入(也称为数据驱动的测试)测试您的代码.此功能很容易被滥用,所以请在锻炼时锻炼你的良好感觉!
我认为在执行以下操作时我确实"滥用"了系统,并希望听取您对此事的意见和建议.
假设我们有以下代码:
template<typename T>
struct SumMethod {
T op(T x, T y) { return x + y; }
};
// optimized function to handle different input array sizes
// in the most efficient way
template<typename T, class Method>
T f(T input[], int size) {
Method m;
T result = (T) 0;
if(size <= 128) {
// use m.op() to compute result etc.
return result;
}
if(size <= 256) {
// use m.op() to compute result etc. …Run Code Online (Sandbox Code Playgroud) 我有一个函数,它从树中递归地创建一个扁平的矩阵列表,这些矩阵必须是可变的,因为它们的元素在创建过程中经常更新.到目前为止,我已经提出了一个具有签名的递归解决方案:
doAll :: .. -> [ST s (STArray s (Int, Int) Int)]
Run Code Online (Sandbox Code Playgroud)
我不[UArray (Int,Int) Int]直接返回的原因是因为doAll递归调用,修改列表中矩阵的元素并附加新矩阵.我不想不必要地冻结和解冻基质.
到现在为止还挺好.我可以检查n-th矩阵(类型Array (Int, Int) Int)ghci
runSTArray (matrices !! 0)
runSTArray (matrices !! 1)
Run Code Online (Sandbox Code Playgroud)
事实上,我的算法得到了正确的结果.但是,我没有找到一种方法来映射runSTUArray返回的列表doAll:
map (runSTArray) matrices
Couldn't match expected type `forall s. ST s (STArray s i0 e0)'
with actual type `ST s0 (STArray s0 (Int, Int) Int)'
Run Code Online (Sandbox Code Playgroud)
如果我尝试在列表上递归计算或尝试评估函数中包含的单个元素,则会出现同样的问题
有人可以解释一下发生了什么(我真的不明白forall关键字的含义)以及如何评估列表中的数组?
没有经验shared_ptr<>我想知道以下是否是一个合适的用例,以及返回shared_ptr<>给用户是否是一个好主意.
我有一个结构图,节点之间有多个连接.在遍历图形期间,为每个节点分配一个值(从连接的节点计算),并且我希望用户能够轻松地访问该值.整个事情看起来(强烈简化)像这样:
class Pool;
class Node {
public:
typedef std::tr1::shared_ptr<Node> Ptr;
...
void compute_dependencies() {
...
// calls Pool to get a new Node instance
dependencies_.push_back(Pool::create_node(...));
...
}
// evaluate the current node
void evaluate() { /* use dependencies_ */ };
double value() const { if(evaluated) return value_; };
private:
std::vector<Node::Ptr> dependencies_; // vector<Node*> better?
dbl value_;
}
// Pool creates and owns all nodes
class Pool {
public:
static const Node::Ptr create_node(...); // create a …Run Code Online (Sandbox Code Playgroud) 对于Haskell来说还是新手,我已经碰到了以下内容:
我试图定义一些类型类来概括一堆使用高斯消元法求解线性方程组的函数.
给定一个线性系统
M x = k
Run Code Online (Sandbox Code Playgroud)
类型a的元素m(i,j) \elem M可以与不同类型b的x和k.为了能够解决系统,a应该是一个实例,Num并且b应该有乘法/加法运算符b,如下所示:
class MixedRing b where
(.+.) :: b -> b -> b
(.*.) :: (Num a) => b -> a -> b
(./.) :: (Num a) => b -> a -> b
Run Code Online (Sandbox Code Playgroud)
现在,即使在这些运算符最简单的实现中,我也会遇到Could not deduce a ~ Int. a is a rigid type variable错误(让我们忘记./.哪些需要Fractional)
data Wrap = …Run Code Online (Sandbox Code Playgroud) 在研究粒子相互作用的模拟时,我偶然发现Morton-order(Z-order)(维基百科链接)中的网格索引,这被认为是提供有效的最近邻细胞搜索.我读过的主要原因是内存中空间紧密单元的几乎顺序排序.
处于第一个实现的中间,我无法围绕如何有效地实现最近邻居的算法,特别是与基本的统一网格相比.
给定单元(x,y),获得8个相邻单元索引并计算相应的z索引是微不足道的.虽然这为元素提供了恒定的访问时间,但是要在预定义的表中计算或查找z-index(对于每个轴和OR'ing分开).这怎么可能更有效率?是否正确,按顺序访问数组A中的元素说A [0] - > A 1 - > A [3] - > A [4] - > ...比A顺序更有效[1023] ] - > A [12] - > A [456] - > A [56] - > ......?
我预计存在一种更简单的算法来查找z次序中的最近邻居.顺便说一句:找到邻居的第一个单元格,迭代.但这不可能是真的,因为这只能在2 ^ 4大小的块内很好地工作.然而,存在两个问题:当小区不在边界上时,可以容易地确定该块的第一个小区并且遍历该块中的小区,但是必须检查该小区是否是最近邻居.当细胞位于边界上时,情况更糟,而不是必须考虑2 ^ 5个细胞.我在这里错过了什么?是否有一个相对简单而有效的算法可以满足我的需求?
第1点中的问题很容易测试,但我不太熟悉所描述的访问模式生成的基本指令,并且非常希望了解幕后发生的事情.
在此先感谢任何帮助,参考等...
关于第2点:我应该补充一点,我理解如何为R ^ d中的点云构建Morton有序数组,其中索引i = f(x1,x2,...,xd)是从逐位交织等获得的.我试图理解的是,是否有比下面的天真ansatz更好的方法来获得最近的邻居(这里是d = 2,"伪代码"):
// Get the z-indices of cells adjacent to the cell containing (x, y)
// Accessing the contents of the cells is irrelevant here
(x, y) \elem R^2 …Run Code Online (Sandbox Code Playgroud) 我必须计算大量的3d向量,并使用带有重载运算符+和运算符*的向量类与单独组件的总和进行比较,显示大约三倍的性能差异.我知道假设差异必须是由于在重载运算符中构造对象.
如何避免施工并提高性能?
我特别困惑,因为以下基本上是afaik基本上做标准的方式,我希望编译器优化它.在现实生活中,总和不是在循环内完成的,而是在相当大的表达式(总可执行的几十MB)中总结不同的向量,这就是为什么在下面使用operator +的原因.
class Vector
{
double x,y,z;
...
Vector&
Vector::operator+=(const Vector &v)
{
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Vector
Vector::operator+(const Vector &v)
{
return Vector(*this) += v; // bad: construction and copy(?)
}
...
}
// comparison
double xx[N], yy[N], zz[N];
Vector vec[N];
// assume xx, yy, zz and vec are properly initialized
Vector sum(0,0,0);
for(int i = 0; i < N; ++i)
{
sum = sum + vec[i]; …Run Code Online (Sandbox Code Playgroud) 对于我的应用程序,我必须处理一堆对象(比如ints),这些对象随后被分割并分类成更小的桶.为此,我将元素存储在一个连续的数组中
arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14...}
Run Code Online (Sandbox Code Playgroud)
并且关于桶(子列表)的信息由相应桶中的第一个元素的偏移量和子列表的长度给出.
所以,例如,给定
offsets = {0,3,8,..}
sublist_lengths = {3,5,2,...}
Run Code Online (Sandbox Code Playgroud)
会导致以下分裂:
0 1 2 || 3 4 5 6 7 || 8 9 || ...
Run Code Online (Sandbox Code Playgroud)
我正在寻找的只是使用自定义内核或thrust库在桶上运行算法(如减少)的一种通用且有效的方法.总结水桶应该给:
3 || 25 || 17 || ...
Run Code Online (Sandbox Code Playgroud)
我想出了什么:
选项1:自定义内核需要相当多的修补,复制到共享内存,正确选择块和网格大小以及自己的算法实现,如扫描,减少等.此外,每个操作都需要自己定制核心.总的来说,我很清楚如何做到这一点,但在thrust过去几天使用后,我的印象是可能有更聪明的方式
选项2:从偏移量({0,0,0,1,1,1,1,1,2,2,3,...}在上面的例子中)生成一个键数组并使用thrust::reduce_by_key.不过,我不喜欢额外的列表生成.
选项3:thrust::transform_iterator与...一起使用thrust::counting_iterator以生成上面给出的密钥列表.不幸的是,我无法想出一个实现,它不需要将索引增加到设备上的偏移列表,并且会破坏并行性.
实现这一目标最理智的方式是什么?
c++ ×6
haskell ×3
arrays ×2
c ×2
state ×2
algorithm ×1
cuda ×1
data-driven ×1
gcc ×1
googletest ×1
interpreter ×1
ownership ×1
parsing ×1
shared-ptr ×1
testing ×1
thrust ×1
typeclass ×1