在几个顺序数组元素中输入相同的值



所以我发现了这个:

std::fill_n(array, 100, value);

但我怀疑这可能不是我想要的。我有一个appay*指针,需要快速地在几个顺序元素中输入相同的值,因为它们是像素,而且有很多。

所以我使用:

*(pointer)=*(pointer+1)=value;

有时(指针)=(指针+1)=*(指针+2)=值;但第一种情况最为关键。我知道,一个额外的"+"不是问题,但当我使用SDL的功能来填充屏幕黑色(或其他)时,它的工作速度有点快,我不知道它是如何优化的。

所以,如果我需要在数组的几个相邻元素中代价高昂地输入相同的值,有什么很酷的技巧吗。

也许有一些转换为(Uint64)和<lt;32将两个相同的值放在两个整数中的技巧?

好吧,对不起,我从一开始就没有解释这是为了什么。所以我渲染体素对象,有时在旋转后,对象内部的屏幕上会有斑点,没有像素被淹没,因为我只绘制对象的外层。我想通过将物体向右拉伸一个像素来进行平滑处理。所以当我放像素的时候,我需要把一个像他一样的像素放在他的右边。

如果你想填充100个(甚至1000个)unsigned int元素,那么你可以选择任何你想要的方法,无论是std::fill_n还是for循环——这个数字太小了,即使你经常做这个操作,你也看不到区别。

然而,如果你想为更大的数组设置值,比如,像素由4个无符号颜色分量组成的8k x 8k纹理,那么你可以使用以下方法进行简短的比较:

#include <iostream>
#include <ctime>
#include <cstdint>
int main(){
    long unsigned const size = 8192 * 8192 * 4;
    unsigned* arr = new unsigned[size];
    clock_t t1 = clock();
    memset(arr, 0, size*sizeof(unsigned));
    clock_t t2 = clock();
    std::fill_n(arr, size, 123);
    clock_t t3 = clock();
    for(int i = 0; i < size; ++i)
        *(arr + i) = 123;
    clock_t t4 = clock();
    int64_t val = 123;
    val = val << 32 | 132;
    for(int i = 0; i < size / 2; ++i)
        *(int64_t*)(arr + i * 2) = val;
    clock_t t5 = clock();
    std::cout << "memset = " << t2 - t1 << std::endl;
    std::cout << "std::fill_n = " << t3 - t2 << std::endl;
    std::cout << "for 32 = " << t4 - t3 << std::endl;
    std::cout << "for 64 = " << t5 - t4 << std::endl;
    delete arr;
    return 0;
}

1.memset

此函数仅用于显示与其他方法相比,归零数组的速度。这是最快的解决方案,但只有当您想将每个字节设置为相同的值时才可用(我想,在您的情况下,00xFF尤其有用)。

2.具有32位值的std::fill_nfor循环

std::fill_n看起来是最慢的解决方案,它甚至比具有32位值的for解决方案稍微慢。

3.64位系统上具有64位值的for循环

我想这是你可以追求的解决方案,因为它赢得了这场比赛。然而,如果您的机器是32位的,那么我希望结果与具有32位值的循环相当(取决于编译器和处理器),因为处理器将把一个64位值处理为两个32位值。

是的,您可以使用一个64位变量将一个值放入两个(或多个)32位(或更小)的连续元素中。有很多如果。显然,您应该使用64位patform,并且应该知道您的平台是如何处理对齐的。

有点像这样:

uint32_t  val = ...;
uint64_t  val2 = val;
(val2  <<= 32) |= val;
for (uint32_t* p = ...; ...)
     *(uint64_t*) p = val2;

如果使用SSE,则可以使用效果更大的类似技术。

最新更新