相关疑难解决方法(0)

为什么malloc + memset比calloc慢?

众所周知,它与初始化分配的内存calloc不同malloc.使用时calloc,内存设置为零.使用时malloc,内存不会被清除.

所以在日常工作中,我认为calloc是malloc+ memset.顺便说一下,为了好玩,我为基准编写了以下代码.

结果令人困惑.

代码1:

#include<stdio.h>
#include<stdlib.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
        int i=0;
        char *buf[10];
        while(i<10)
        {
                buf[i] = (char*)calloc(1,BLOCK_SIZE);
                i++;
        }
}
Run Code Online (Sandbox Code Playgroud)

代码1的输出:

time ./a.out  
**real 0m0.287s**  
user 0m0.095s  
sys 0m0.192s  
Run Code Online (Sandbox Code Playgroud)

代码2:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
        int i=0;
        char *buf[10];
        while(i<10)
        {
                buf[i] = (char*)malloc(BLOCK_SIZE);
                memset(buf[i],'\0',BLOCK_SIZE);
                i++;
        }
}
Run Code Online (Sandbox Code Playgroud)

代码2的输出:

time ./a.out   
**real 0m2.693s**  
user 0m0.973s  
sys 0m1.721s  
Run Code Online (Sandbox Code Playgroud)

更换 …

c malloc

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

我们需要预先分配.但是MATLAB没有预先分配预分配?

在测试是否any()短路时(确实如此!)我在预分配测试变量时发现了以下有趣的行为:

test=zeros(1e7,1);
>> tic;any(test);toc
Elapsed time is 2.444690 seconds.
>> test(2)=1;
>> tic;any(test);toc
Elapsed time is 0.000034 seconds.
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做:

test=ones(1e7,1);
test(1:end)=0;
tic;any(test);toc
Elapsed time is 0.642413 seconds.
>> test(2)=1;
>> tic;any(test);toc
Elapsed time is 0.000021 seconds.
Run Code Online (Sandbox Code Playgroud)

事实证明,这是因为变量在完全填充信息之前并不真正在RAM上,因此第一次测试需要更长时间,因为它需要分配它.我检查这个的方法是查看Windows任务管理器中使用的内存.

虽然这可能有些意义(不要在需要之前进行初始化),但让我更加困惑的是下面的测试,其中变量填充在for循环中,并且在某些时候执行被停止.

test=zeros(1e7,1);

for ii=1:1e7
    test(ii)=1;
    if ii==1e7/2
        pause
    end
end
Run Code Online (Sandbox Code Playgroud)

在检查MATLAB使用的内存时,我可以看到当停止时,它只使用了50%的test所需内存(如果已满).这可以用不同的记忆百分比再现.

有趣的是,以下内容也没有分配整个矩阵.

test=zeros(1e7,1);
test(end)=1;
Run Code Online (Sandbox Code Playgroud)

我知道MATLAB不是动态分配和增加test循环的大小,因为这会使结束迭代非常慢(由于需要高memcopys),并且它也会在我提出的最后一次测试中分配整个数组.所以我的问题是:

到底是怎么回事?

有人建议这可能与虚拟内存和物理内存有关,并且与操作系统看待内存的方式有关.不知道如何链接到这里提出的第一个测试.任何进一步的解释都是理想的.

赢得10 x64,MATLAB 2017a

ram matlab memory-management

14
推荐指数
1
解决办法
335
查看次数

是否有一种快速(呃)方法从方阵中删除所有非对角线元素?

我在应用程序中有一个小的性能瓶颈,需要从大的方阵中删除非对角元素.所以,矩阵x

17    24     1     8    15
23     5     7    14    16
 4     6    13    20    22
10    12    19    21     3
11    18    25     2     9
Run Code Online (Sandbox Code Playgroud)

变

17     0     0     0     0
 0     5     0     0     0
 0     0    13     0     0
 0     0     0    21     0
 0     0     0     0     9
Run Code Online (Sandbox Code Playgroud)

问题:下面的bsxfun和diag解决方案是迄今为止最快的解决方案,我怀疑我可以在保持Matlab代码的同时改进它,但有更快的方法吗?

解决方案

这是我到目前为止所想到的.

通过单位矩阵执行逐元素乘法.这是最简单的解决方案:

y = x .* eye(n);
Run Code Online (Sandbox Code Playgroud)

使用bsxfun和diag:

y = bsxfun(@times, diag(x), eye(n));
Run Code Online (Sandbox Code Playgroud)

下/上三角矩阵:

y = x - …
Run Code Online (Sandbox Code Playgroud)

matlab matrix

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

初始化非标准值的双数组的最快方法

MATLAB提供了预分配/初始化数组的函数,这些数组具有常见值,如0或1.但是,如果我们希望数组具有一些任意double值,那么有多种方法可以做到这一点,并且不明显哪一个更可取.

这个问题并不新鲜 - 以前在这篇博客文章和本回答中讨论过这个问题.但是,经验表明,软件(特别是MATLAB及其执行引擎)和硬件随时间而变化,因此最佳方法可能在不同系统上有所不同.不幸的是,前面提到的资源不提供基准测试代码,这可能是回答这个问题的最终(和永恒)方式.

我正在寻找一个可以运行的基准测试,它可以告诉我在我的系统上使用最快的方法,考虑到我可能正在使用各种大小的"常规" double数组和gpuArray double数组.

arrays performance matlab gpgpu initialization

4
推荐指数
1
解决办法
66
查看次数

MATLAB:更快地预分配零矩阵

/ edit:有关该主题的有趣讨论,请参阅此处.谢谢@Dan


使用a(m,n) = 0的似乎更快,这取决于基体的大小a比a = zeros(m,n).在循环之前进行预分配时,两种变体是否相同?

matlab loops memory-management

2
推荐指数
1
解决办法
484
查看次数

从分类数组转向二进制矩阵

我有一个数组,其中包含一些属于集合的值.我想在二进制矩阵中转换此数组,此矩阵的每一列将表示该集合的每个可能值,对于与输入数组匹配的列,行值为1,对于所有其他列,行值为0.我认为这个名字就像二元枢轴.

输入数组是表类型的列

输入数组的示例(前面的示例只是大写字母,导致误解):

'Apple'
'香蕉'
'樱桃'
'Dragonfruit''Apple
'
'樱桃'

所以,在这个例子中,输入可以假设4个不同的值:'Apple','Banana','Cherry'或'Dragonfruit',在我的真实场景中它可以超过4.

示例输出矩阵:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
1 0 0 0
0 0 1 0

我已经实现了这种期望的行为,但我想知道是否有更好的方法来执行此操作.以矢量化方式(没有每个类别的for循环)或使用内置函数.

 function [ binMatrix, categs ] = pivotToBinaryMatrix( input )
      categorizedInput = categorical(input);

      categs = categories(categorizedInput);

      binMatrix = zeros(size(atributo, 1), size(categorias, 1));

      for i = 1: size(caters,1)
           binMatrix(:,i) = ismember(categorizedInput, categs(i));
      end
 end
Run Code Online (Sandbox Code Playgroud)

对于包含9个类别的约50,000个条目,它在0.075137秒内执行.

编辑:我改进了这些例子,因为之前的例子导致了误解.

arrays performance matlab for-loop vectorization

2
推荐指数
1
解决办法
131
查看次数

构建一个具有交替的正负元素的数组的最快方法是从matlab中的向量中获取的?

我有一个具有如下值的向量[2,3,4,5,6,7...],我想构造一个数组,它重复原始向量中的值,但在它之后也有原始值的负数.因此,给定向量的结果数组将是[2, -2, 3, -3, 4, -4...].在matlab中最好的方法是什么?

arrays matlab vector

2
推荐指数
1
解决办法
288
查看次数

在MATLAB中改善循环性能

有没有办法通过这种操作来提高性能?

t=0:0.01:100;
f=@(t,l) exp(-t.*l)
l=[0.1:0.5:100];
for ll=1:length(l)
    a(ll,:)=f(t,l(ll));
end 
Run Code Online (Sandbox Code Playgroud)

在这些情况下,我想不出任何避免循环的方法.

任何帮助表示赞赏.

arrays optimization performance matlab vectorization

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

取两个向量的元素并在Matlab中组合它们

你能不能帮我在Matlab中写下一个非常快速的算法,它执行以下操作:我有维度和维度的2向量.我想构建尺寸,使得Anx1Bnx1C2nx1

C(1)=A(1), C(2)=B(1), C(3)=A(2), C(4)=B(2), C(5)=A(3), C(6)=B(3), ... 
Run Code Online (Sandbox Code Playgroud)

我虽然关于

C=[];
for j=1:n
    C=[C; [A(j) B(j)]'];
end
Run Code Online (Sandbox Code Playgroud)

你知道更快更有效的事情吗?

例:

n=9
A=[1 3 5 7 9 11 13 15 17]';
B=[2 4 6 8 10 12 14 16 18]';
C=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]';
Run Code Online (Sandbox Code Playgroud)

arrays matlab

0
推荐指数
1
解决办法
136
查看次数

在matlab中生成向量

我想生成一个看起来像这样的向量:[1,0,0 ...... 0,1],但我不知道如何在不使用for的情况下做到这一点.我可以生成各种矩阵格式,但是这个我无法弄清楚应该怎么做.

matlab

-2
推荐指数
1
解决办法
91
查看次数