- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我必须执行 Cannon's Algorithm这是一种并行算法,用于乘以维度为正方形的矩阵,维度可以被处理器数量的平方根整除。我写的这段代码运行得很好,但在生活中运行而不会崩溃只是故事的一半。它不会正确地将 A x B 乘以新矩阵 C。这是代码,请帮助我并引导我帮助我解决我做错的事情。很明显,这是家庭作业。
void shift_left(datatype** mat, int s, int row, int n, int amount) {
datatype* temp_buffer = malloc(sizeof(datatype) * n);
for(int col = 0; col < n; col++) {
datatype temp = mat[row][(col+amount)%s];
temp_buffer[(col+amount)%s] = mat[row][col];
temp_buffer[col] = temp;
}
memcpy(mat[row], temp_buffer, n);
free(temp_buffer);
}
void shift_up(datatype** mat, int s, int col, int n, int amount) {
datatype* temp_buffer = malloc(sizeof(datatype) * n);
for(int row = 0; row < n; row++) {
datatype temp = mat[(row+amount)%s][col];
temp_buffer[(row+amount)%s] = mat[row][col];
temp_buffer[row] = temp;
}
memcpy(&mat[0][col], temp_buffer, n);
free(temp_buffer);
}
void cannon_mul(int p_sqrt,datatype** a, datatype** b, datatype** c, int n) {
/* 2D matrices and n^2 sized only!*/
int i = 0, j = 0, k = 0;
int s = p_sqrt;
for(i = 0; i < (s-1); i++) {
shift_left(a, s, i, s-1, i); // Skew matrix a
}
for (i = 0; i < (s-1); i++) {
shift_up(b, s, i, s-1, i); // Skew matrix b
}
for(k = 0; k < (s-1); k++) {
for(i = 0; i < (s-1); i++) {
for(j = 0; j < (s-1); j++) {
c[i][j] += a[i][j]*b[i][j];
shift_left(a, s, i, s-1, 1);
shift_up(b, s, i, s-1, 1);
}
}
}
}
我的预感是移位错误或者我遗漏了算法的重要部分。我原来的 shift 函数没有使用临时缓冲区,所以这次我想使用临时缓冲区,但这并没有什么区别。如果有帮助,我可以显示一些示例输出,但结果不甚至与期望的结果相差甚远。好消息它运行得很快:)
1.48 0.14 9.47 8.99 8.06 0.06 6.68 1.04 4.44 7.50
7.26 8.87 2.21 6.27 2.12 7.91 0.65 5.24 0.45 4.94
0.47 4.13 1.87 2.25 6.83 1.52 6.41 9.14 9.22 8.91
7.34 2.70 6.78 2.78 3.51 4.95 5.27 0.85 9.51 6.82
0.28 6.73 0.70 8.88 7.14 9.09 2.36 5.38 6.43 9.00
7.13 6.71 6.92 9.81 5.13 9.35 7.50 5.16 4.68 3.62
1.30 6.26 4.55 4.27 0.51 2.23 3.19 8.75 6.57 9.07
7.49 6.41 1.04 7.78 7.16 2.78 2.25 6.23 9.42 0.32
3.21 3.60 2.04 2.93 4.29 3.88 2.78 8.01 4.57 6.47
7.52 3.77 0.63 5.97 7.32 4.90 9.63 4.90 8.46 1.90
用我的代码将上面的矩阵与自身相乘产生:
2.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
50.81 0.00 0.00 0.00 0.00 87.51 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
顺序程序产生这个结果:
163.41 212.17 144.32 227.10 251.03 205.60 245.63 277.33 368.99 334.11
257.85 230.82 203.60 314.08 246.02 240.12 228.37 197.90 264.38 228.24
234.13 272.10 110.75 294.84 263.16 242.07 209.54 316.13 339.23 260.51
185.33 215.59 192.26 283.31 270.80 208.38 265.08 291.49 312.24 319.73
313.23 301.95 182.04 348.11 283.20 337.49 266.54 284.57 355.28 281.07
293.25 323.29 281.35 393.92 325.24 313.62 313.48 342.95 418.37 401.91
255.88 238.25 122.17 254.52 243.58 204.49 217.69 273.03 314.89 214.45
219.26 239.07 200.18 309.98 262.21 242.68 190.02 245.85 297.96 308.56
209.03 213.11 126.24 266.48 233.88 199.33 193.28 228.92 277.50 202.27
210.31 264.67 227.59 337.79 261.40 250.35 225.77 295.00 331.92 352.17
重要的是要注意我正在展示我的程序的相关部分,如果您觉得我需要展示更多请这样做,我将提供更多代码。最后,为什么作业标签不见了?
一个人指出缓冲区太小并且缺少 sizeof 是一个愚蠢的错误,现在已更正。我试过了,我得到了相同的结果,所以显然问题与此无关。希望在 2 天内我可以开赏金来吸引一些人至少给我一个问题所在的线索。这是一个我似乎无法调试的错误,我必须承认这个算法的理解是零到零。我依赖的网络资源对增加我的理解作用甚微。
尝试使用 calloc 来零分配缓冲区,但它不会改变结果。很奇怪,但谢谢你的建议;我忘了内存没有分配归零。
我试过这个:
void shift_left(datatype** mat, int s, int row, int n, int amount) {
datatype* temp_buffer = calloc(n, sizeof(datatype) * n);
for(int col = 0; col < n; col++) {
/* temp_buffer[(col+amount)%s] = mat[row][col];
temp_buffer[col] = mat[row][(col+amount)%s]; */
temp_buffer[(col+amount)%s] = 0;
temp_buffer[col] = 0;
}
memcpy(mat[row], temp_buffer, sizeof(datatype) * n);
//free(temp_buffer);
}
void shift_up(datatype** mat, int s, int col, int n, int amount) {
datatype* temp_buffer = calloc(n, sizeof(datatype) * n);
for(int row = 0; row < n; row++) {
/* temp_buffer[(row+amount)%s] = mat[row][col];
temp_buffer[row] = mat[(row+amount)%s][col]; */
temp_buffer[(row+amount)%s] = 0;
temp_buffer[row] = 0;
}
memcpy(&mat[0][col], temp_buffer, sizeof(datatype) * n);
free(temp_buffer);
}
令人惊讶的是,结果是一样的。自从我注释了代码并将其替换为零后,它什么时候应该打印全零。我猜 memcpy 不工作。
我已经确认 memcpy 是罪魁祸首。但是为什么我不知道我被难住了,如果它有助于 datatype is just an alias for double 教授出于某种奇怪的原因写道,因为它确实无助于使代码更具可读性。
但如果我确实自己解决了它,我会很乐意展示我的问题的解决方案。
最佳答案
副本太小。
// memcpy(mat[row], temp_buffer, n);
memcpy(mat[row], temp_buffer, n * sizeof(datatype) );
同样适用于 memcpy(&mat[0][col], temp_buffer, n);
关于c - 实现 Cannon 的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29637513/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!