使用特征向量化表达式

发布于 2024-12-09 00:27:47 字数 850 浏览 0 评论 0原文

在我的程序中(使用 Eigen 库),我需要对 2D 向量进行操作。在我的内部循环中,我有以下函数:

static inline double eval(double x, double y, double xi, double yi)
{
    const double invlen2  = 1/(x*x + y*y);
    const double invlen4 = invlen2*invlen2;
    const double invlen6 = invlen4*invlen2;

    const double x2  = x*x,   y2  = y*y;
    const double x3  = x2*x,  y3  = y2*y;
    const double xi2 = xi*xi, yi2 = yi*yi;

    return x*invlen2 + invlen4*(x2*xi + 2*x*y*yi - xi*y2)
    + invlen6*(x3*xi2 + 3*x*y2*yi2 + 6*x2*y*xi*yi - 3*x*xi2*y2 - 2*y3*xi*yi - x3*yi2);
}

void f(Vector2d& out, const Vector2d& R, const Vector2d& r)
{
    out.x() = eval(R.x(), R.y(), r.x(), r.y());
    out.y() = eval(R.y(), R.x(), r.y(), r.x());
}

这个表达式虽然很混乱,但似乎是矢量化的主要候选者,因为 x()y() 计算遵循相同的路径。我的问题是如何使用 Eigen 来完成此操作,而无需手动下拉到程序集。

In my program -- which uses the Eigen library -- I need to operate on 2D vectors. In my inner loop I have the following function:

static inline double eval(double x, double y, double xi, double yi)
{
    const double invlen2  = 1/(x*x + y*y);
    const double invlen4 = invlen2*invlen2;
    const double invlen6 = invlen4*invlen2;

    const double x2  = x*x,   y2  = y*y;
    const double x3  = x2*x,  y3  = y2*y;
    const double xi2 = xi*xi, yi2 = yi*yi;

    return x*invlen2 + invlen4*(x2*xi + 2*x*y*yi - xi*y2)
    + invlen6*(x3*xi2 + 3*x*y2*yi2 + 6*x2*y*xi*yi - 3*x*xi2*y2 - 2*y3*xi*yi - x3*yi2);
}

void f(Vector2d& out, const Vector2d& R, const Vector2d& r)
{
    out.x() = eval(R.x(), R.y(), r.x(), r.y());
    out.y() = eval(R.y(), R.x(), r.y(), r.x());
}

This expression, although messy, seems like a prime candidate for vectorisation as both the x() and y() computations follow identical paths. My question is how to do it with Eigen without needing to manually drop down to assembly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终止放荡 2024-12-16 00:27:47

这个答案与 Eigen 无关,但既然你提到手动下降到程序集,我将添加这个。

您不需要使用汇编来矢量化代码。有一些编译器内在函数可以让手动矢量化而无需汇编:

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_overview.htm#intref_overview

也就是说:看起来 Eigen 已经内部支持矢量化,但它似乎不适用于您的示例。所以我明白你为什么要手动执行此操作。

This answer has nothing to do with Eigen, but since you mentioned manually dropping down to assembly, I'll add this.

You don't need to use assembly to vectorize code. There are compiler intrinsics that will let manually vectorize without assembly:

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_overview.htm#intref_overview

That said: It looks like Eigen already has internal support for vectorization, but it doesn't appear to be applicable in your example. So I can see why you want to do it manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文