- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我使用C++和CUDA/C,想为特定问题编写代码,但遇到了一个非常棘手的简化问题。
我在并行编程方面的经验不容忽视,但相当有限,我无法完全预见到此问题的特殊性。
我怀疑是否有一种方便甚至“轻松”的方式来处理我面临的问题,但也许我错了。
如果有任何涵盖此问题或类似问题的资源(例如文章,书籍,网络链接等)或关键字,请告知我。
我试图将整个案例尽可能地概括,并使其抽象化,而不是发布过多的代码。
布局 ...
我有一个由N个初始元素和N个结果元素组成的系统。 (例如,我将使用N = 8,但N可以是大于3的任何整数值。)
static size_t const N = 8;
double init_values[N], result[N];
f(init_values[0],init_values[1])
,
f(init_values[0],init_values[2])
,...,
f(init_values[0],init_values[N-1])
,
f(init_values[1],init_values[2])
,...,
f(init_values[1],init_values[N-1])
,...等等。
P 0 1 2 3 4 5 6 7
|---------------------------------------
0| x
|
1| 0 x
|
2| 1 2 x
|
3| 3 4 5 x
|
4| 6 7 8 9 x
|
5| 10 11 12 13 14 x
|
6| 15 16 17 18 19 20 x
|
7| 21 22 23 24 25 26 27 x
init_values
中相应列和行元素的函数。
P[i] (= P[row(i)][col(i]) = f(init_values[col(i)], init_values[row(i)])
P[11] (= P[5][1]) = f(init_values[1], init_values[5])
(N*N-N)/2 = 28
,有
P[1][5]==P[5][1]
可能是唯一的组合(注意:
N = 8
,所以我们只有一个较低(或较高)的三角矩阵)。
result[3] = (P[3]+P[4]+P[5]) - (P[9]+P[13]+P[18]+P[24])
result[3] = sum_elements_row(3) - sum_elements_column(3)
N-1
操作(潜在的并发写入)将在每个result[i]
上执行result[i]
将通过减法和N-(i+1)
加法得到i
写入P[i][j]
中传出的内容将对r[j]
进行减法运算,并对r[i]
进行加法运算struct combo { size_t row,col; };
,需要在
vector<combo>
中计算并在此 vector 上进行操作。 (由当前实现使用)
std::vector<combo> elements;
// somehow fill
size_t const M = elements.size();
for (size_t i=0; i<M; ++i)
{
// do the necessary computations using elements[i].row and elements[i].col
}
size_t M = (N*N-N)/2;
for (size_t i=0; i<M; ++i)
{
// calculate row indices from `i`
double tmp = sqrt(8.0*double(i+1))/2.0 + 0.5;
double row_d = floor(tmp);
size_t current_row = size_t(row_d);
size_t current_col = size_t(floor(row_d*(ict-row_d)-0.5));
// check whether the current combo of row and col is not to be removed
if (!removes[current_row].exists(current_col))
{
// do the necessary computations using current_row and current_col
}
}
removes
vector 相比, vector
elements
非常小,但是用于获得
current_row
,
current_col
和if分支的额外计算效率非常低。
calc_non_skipped() != calc_all() - calc_skipped()
combo
的 vector ,该 vector 存储需要计算的每个P并将其传递给并行的for循环。
最佳答案
首先,我有些困惑,为什么(N**2 - N)/2
在N = 7时会产生27 ...但是对于索引0-7,N = 8来说,P中有28个元素。所以在今晚不要尝试回答这样的问题那天。 :-)
但是有一个潜在的解决方案:您是否需要将阵列P保留用于其他目的?如果没有,我认为您可以使用两个中间数组来获得所需的结果,每个中间数组的长度为N:一个用于行的总和,一个用于列的总和。
这是我想尝试做的一个简单示例(子例程direct_approach()
),以及如何使用中间数组(子例程refined_approach()
)实现相同的结果:
#include <cstdlib>
#include <cstdio>
const int N = 7;
const float input_values[N] = { 3.0F, 5.0F, 7.0F, 11.0F, 13.0F, 17.0F, 23.0F };
float P[N][N]; // Yes, I'm wasting half the array. This way I don't have to fuss with mapping the indices.
float result1[N] = { 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F };
float result2[N] = { 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F };
float f(float arg1, float arg2)
{
// Arbitrary computation
return (arg1 * arg2);
}
float compute_result(int index)
{
float row_sum = 0.0F;
float col_sum = 0.0F;
int row;
int col;
// Compute the row sum
for (col = (index + 1); col < N; col++)
{
row_sum += P[index][col];
}
// Compute the column sum
for (row = 0; row < index; row++)
{
col_sum += P[row][index];
}
return (row_sum - col_sum);
}
void direct_approach()
{
int row;
int col;
for (row = 0; row < N; row++)
{
for (col = (row + 1); col < N; col++)
{
P[row][col] = f(input_values[row], input_values[col]);
}
}
int index;
for (index = 0; index < N; index++)
{
result1[index] = compute_result(index);
}
}
void refined_approach()
{
float row_sums[N];
float col_sums[N];
int index;
// Initialize intermediate arrays
for (index = 0; index < N; index++)
{
row_sums[index] = 0.0F;
col_sums[index] = 0.0F;
}
// Compute the row and column sums
// This can be parallelized by computing row and column sums
// independently, instead of in nested loops.
int row;
int col;
for (row = 0; row < N; row++)
{
for (col = (row + 1); col < N; col++)
{
float computed = f(input_values[row], input_values[col]);
row_sums[row] += computed;
col_sums[col] += computed;
}
}
// Compute the result
for (index = 0; index < N; index++)
{
result2[index] = row_sums[index] - col_sums[index];
}
}
void print_result(int n, float * result)
{
int index;
for (index = 0; index < n; index++)
{
printf(" [%d]=%f\n", index, result[index]);
}
}
int main(int argc, char * * argv)
{
printf("Data reduction test\n");
direct_approach();
printf("Result 1:\n");
print_result(N, result1);
refined_approach();
printf("Result 2:\n");
print_result(N, result2);
return (0);
}
int valid_indices[] = { 0, 1, 3, 4, 6 };
valid_indices
,并使用这些索引从输入数组中检索数据以计算结果。另一方面,如果要跳过的值取决于P数组的两个索引,那么我看不到如何避免某种查找。
关于c++ - 高效布局和减少虚拟2D数据(抽象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16399222/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我试图用这种形式简单地获取数字 28 integer+space+integer+integer+space+integer我试过这个正则表达式 \\s\\d\\d\\s 但我得到了两个数字11 和
最近一直在学习D语言。我一直对运行时感到困惑。 从我能收集到的关于它的信息中,(这不是很多)我知道它是一种有助于 D 的一些特性的运行时。像垃圾收集一样,它与您自己的程序一起运行。但是既然 D 是编译
想问一下这两个正则表达式有区别吗? \d\d\d 与 \d{3} 我已经在我的本地机器上使用 Java 和 Windows 操作系统对此进行了测试,两者都工作正常并且结果相同。但是,当在 linux
我正在学习 Go,而且我坚持使用 Go 之旅(exercise-stringer.go:https://tour.golang.org/methods/7)。 这是一些代码: type IPAddr
我在Java正则表达式中发现了一段令我困惑的代码: Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" ); 要编译的字符串是: String string
我在 ruby 代码上偶然发现了这个。我知道\d{4})\/(\d\d)\/(\d\d)\/(.*)/是什么意思,但是\1-\2-\3-\4 是什么意思? 最佳答案 \1-\2-\3-\4 是 b
我一直在努力解决这个问题,这让我很恼火。我了解 D 运行时库。它是什么,它做什么。我也明白你可以在没有它的情况下编译 D 应用程序。就像 XoMB 所做的那样。好吧,XoMB 定义了自己的运行时,但是
我有两个列表列表,子列表代表路径。我想找到所有路径。 List> pathList1 List> pathList2 当然是天真的解决方案: List> result = new ArrayList>
我需要使用 Regex 格式化一个字符串,该字符串包含数字、字母 a-z 和 A-Z,同时还包含破折号和空格。 从用户输入我有02-219 8 53 24 输出应该是022 198 53 24 我正在
目标是达到与this C++ example相同的效果: 避免创建临时文件。我曾尝试将 C++ 示例翻译为 D,但没有成功。我也尝试过不同的方法。 import std.datetime : benc
tl;dr:你好吗perfect forwarding在 D? 该链接有一个很好的解释,但例如,假设我有这个方法: void foo(T)(in int a, out int b, ref int c
有什么方法可以在 D 中使用abstract auto 函数吗? 如果我声明一个类如下: class MyClass { abstract auto foo(); } 我收到以下错误: mai
有没有人为内存中重叠的数组切片实现交集?算法在没有重叠时返回 []。 当 pretty-print (使用重叠缩进)内存中重叠的数组切片时,我想要这个。 最佳答案 如果您确定它们是数组,那么只需取 p
我已经开始学习 D,但我在使用 Andrei Alexandrescu 所著的 The D Programming Language 一书中提供的示例时遇到了一些麻烦。由于 int 和 ulong 类
如何创建一个不可变的类? 我的目标是创建一个实例始终不可变的类。现在我只是用不可变的方法和构造函数创建了一个“可变”类。我将其称为 mData,m 表示可变。然后我创建一个别名 alias immut
不久前我买了《The D Programming Language》。好书,很有教育意义。但是,我在尝试编译书中列出的语言功能时遇到了麻烦:扩展函数。 在这本书中,Andrei 写了任何可以像这样调用
我在 D http://www.digitalmars.com/d/2.0/lazy-evaluation.html 中找到了函数参数的惰性求值示例 我想知道如何在 D 中实现可能的无限数据结构,就像
这个问题在这里已经有了答案: 12 年前关闭。 Possible Duplicate: Could anyone explain these undefined behaviors (i = i++
当前是否可以跨模块扫描/查询/迭代具有某些属性的所有函数(或类)? 例如: source/packageA/something.d: @sillyWalk(10) void doSomething()
我是一名优秀的程序员,十分优秀!