当前位置: 首页 > 知识库问答 >
问题:

为什么Swift在这个图像处理测试中要比C慢100倍呢?[副本]

蒋寒
2023-03-14

测试C:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

uint8_t pixels[640*480];
uint8_t alpha[640*480];
uint8_t blended[640*480];

void blend(uint8_t* px, uint8_t* al, uint8_t* result, int size)
{
    for(int i=0; i<size; i++) {
        result[i] = (uint8_t)(((uint16_t)px[i]) *al[i] /255);
    }
}

int main(void)
{
    memset(pixels, 128, 640*480);
    memset(alpha, 128, 640*480);
    memset(blended, 255, 640*480);

    // Test 10 frames
    for(int i=0; i<10; i++) {
        blend(pixels, alpha, blended, 640*480);
    }

    return 0;
}

我用以下命令在我的Macbook Air 2011上编译了它:

clang -O3 test.c -o test

10帧处理时间约为0.01s。换句话说,处理一帧需要C代码1ms:

$ time ./test
real    0m0.010s
user    0m0.006s
sys     0m0.003s

test.swift:

let pixels = UInt8[](count: 640*480, repeatedValue: 128)
let alpha = UInt8[](count: 640*480, repeatedValue: 128)
let blended = UInt8[](count: 640*480, repeatedValue: 255)

func blend(px: UInt8[], al: UInt8[], result: UInt8[], size: Int)
{
    for(var i=0; i<size; i++) {
        var b = (UInt16)(px[i]) * (UInt16)(al[i])
        result[i] = (UInt8)(b/255)
    }
}

for i in 0..10 {
    blend(pixels, alpha, blended, 640*480)
}

生成命令行是:

xcrun swift -O3 test.swift -o test

在这里,我使用相同的O3级别优化标志,希望使比较公平。然而,所产生的速度却慢了100倍:

$ time ./test

real    0m1.172s
user    0m1.146s
sys     0m0.006s
$ gcc -v
Configured with: --prefix=/Applications/Xcode6-Beta.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.34.4) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.2.0
Thread model: posix
             C Time (s)      Swift Time (s)
  1 frame:     0.005            0.130
 10 frames(*): 0.006            1.196
 20 frames:    0.008            2.397
100 frames:    0.024           11.668

通过@mweathers建议的-ofast,可以将速度提高到合理的范围。

在我的笔记本电脑上,带有-ofast的Swift版本在10帧时的性能为0.013秒,100帧时的性能为0.048秒,接近C语言性能的一半。

共有1个答案

倪德业
2023-03-14

使用:

xcrun swift-ofast test.swift-o test

我得到的次数是:

real    0m0.052s
user    0m0.009s
sys 0m0.005s
 类似资料:
  • 我正在看一看大型矩阵乘法,并运行以下实验以形成一个基线测试: null 以下是Octave/MATLAB实现: 运行: hood下的Octave正在使用BLAS(我假设函数) 有人能解释这种差别吗?BLAS实现的体系结构到底是什么?我看到它在使用Fortran,但是在CPU级别上发生了什么呢?它用的是什么算法?它是如何使用CPU缓存的?它调用什么x86-64机器指令?(是使用AVX这样的高级CPU

  • 问题内容: 我正在研究大型矩阵乘法,并运行以下实验以形成基准测试: 从std normal(0平均值,1 stddev)随机生成两个4096x4096矩阵X,Y。 Z = X * Y Z的元素求和(以确保它们被访问)并输出。 这是朴素的C ++实现: 编译并运行: 这是Octave / matlab实现: 跑: 八度使用BLAS(我承担功能) 硬件是Linux x86-64上的i7 3930X,内

  • 我有一个表,其中有(其他20个)列、和,以及和的索引。该表有大约500k行。 为什么以下to查询在速度上差异如此之大?查询A需要0.3秒,而查询B需要28秒。 查询A 我使用MySQL5.1.34。

  • rank ▲ ✰ vote url 28 556 340 568 url 为什么在C++中读取stdin中的行会比Python慢呢? ps:这个是C++的问题了所以没做翻译.

  • 问题内容: 我正在尝试将一些代码从Python转换为C ,以期提高速度并提高生锈的C 技能。当一个天真的实现从标准输入读取线是在Python比C快得多 (见昨天我惊呆了这个)。今天,我终于弄清楚了如何使用合并定界符(与python的split()相似的语义)在C 中拆分字符串,并且现在遇到了deja vu!我的C ++代码需要花费更长的时间才能完成工作(尽管昨天的课程并没有增加一个数量级)。 Py

  • 我需要在向量中找到max元素,所以我使用了,但我发现它是一个非常慢的函数,所以我编写了自己的版本,并设法获得更好的x3性能,下面是代码: 输出: 平均而言,要比多花费x3个时间。那么为什么我能够这么容易地创建一个更快的std函数呢?既然std这么慢,我是不是应该停止使用std并编写自己的函数呢? 注意:一开始我以为这是因为我在for循环中使用了andinteger而不是迭代器,但现在看来这并不重要